от
(В этом примере не использовались # include, скомпилированные в MacOS10.14, Eclipse IDE, с g , опции -O0 -g3 -Wall -c -fmessage-length = 0) Предполагая это объявление переменной:
int (*fun)(int);
Это не скомпилируется с «недопустимой перегрузкой std :: toupper и std :: tolower».
fun = (1 ? std::toupper : std::tolower);   // ERROR, invalid overload
И это компилируется нормально:
if (1) {
    fun = std::toupper;   // OK
}
else {
    fun = std::tolower;   // OK
}
             

Ваш ответ

Отображаемое имя (по желанию):
Конфиденциальность: Ваш электронный адрес будет использоваться только для отправки уведомлений.
Анти-спам проверка:
Чтобы избежать проверки в будущем, пожалуйста войдите или зарегистрируйтесь.

3 Ответы

0 голосов
от
std::toupper
(1 и 2) и
std::tolower
(1 и 2) перегружены. При определении общего типа между ними для условного оператора (до присвоения
chr2fun
), какую перегрузку следует использовать, невозможно определить. Вы можете использовать
static_cast
, чтобы указать, какой из них следует учитывать. (Предполагается, что принудительное разрешение перегрузки происходит сначала соответственно, затем проблема определения общего типа исчезает.)   
static_cast
также может использоваться для устранения неоднозначности перегрузок функций путем выполнения преобразования функции в указатель в конкретный тип например
chr2fun = (str2modus == STR2UP ? static_cast
0 голосов
от
В первом случае компилятор блокируется, даже не добравшись до назначения. Упрощенное выражение:
(true ? std::toupper : std::tolower)
Не удастся скомпилировать, если имеется несколько перегрузок
toupper
/
tolower
. Это связано с тем, что тип возвращаемого значения троичного оператора должен быть установлен исключительно на основе типов 2-го и 3-го аргументов, не обращая внимания на контекст, в котором используется его результат. Забавно, даже если один из этих аргументов не является перегруженной функцией, этого все же недостаточно. Причины этого менее очевидны и имеют большее отношение к правилам разрешения перегрузки1 и их применению. Приведение - это точно одна из семи возможностей его запуска, а определение целевого типа троичных операторов само по себе не является. В случае прямого присваивания, правые стороны назначения должны соответствовать левым, и поэтому нет никакой двусмысленности. В любом случае, как указывает @Caleth, согласно 16.5.4.2.1.6, этот код имеет неопределенное поведение. 1Справочник C содержит неверный абзац стандарта C . [over.over] на самом деле 12.4.     
0 голосов
от
Этот фрагмент прекрасно компилируется с gcc 9.1.
#include
Добро пожаловать на сайт ByNets, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...