Проблема преобразования указателя с тройным оператором
Вопрос
Я знаю, что у тройного оператора есть некоторые удивительные ограничения, но я был немного сбит с толку, что это не может составить для меня:
void foo(bool b)
{
int* ptr = ((b) ? NULL : NULL);
}
Очевидно, что это минимум, необходимый для того, чтобы показать проблему. Ошибка:
[BCC32 Error] Unit11.cpp(20): E2034 Cannot convert 'int' to 'int *'
Компилятор-это менее чем 100%-ный по Embarcadero C ++ Builder 2010, поэтому ошибка компилятора далеко невозможная ...
Примечание: модифицированы парины, чтобы избежать путаницы по поводу моих намерений.
Примечание2: Я немного смутил, как я попал в эту конструкцию в первую очередь, так что вот мое оправдание: я получал некоторые ошибки компиляции на такой линии, как a = b? c : d
, где B, C и D были все сложные выражения. Чтобы сузить его, я заменил c
а также d
с NULL
S, чтобы проверить, если b
был виновником. На данный момент все пошло в ад в ручной стрельбе.
Решение
NULL
макрос, который расширяется до 0
(или какое -то интегральное постоянное выражение со значением 0
, Например, (1 - 1)
) Это не «особенное».
Любое интегральное постоянное выражение со значением нуля можно использовать в качестве константы нулевого указателя, что является причиной, по которой int* ptr = 0;
разрешено. Однако здесь выражение b ? 0 : 0
; Это не интегральное постоянное выражение (b
не постоянно); его тип int
, что неявенно кабриочнется int*
Обходной путь состоит в том, чтобы явно указать, что вам нужен тип указателя:
int* const null_int_ptr = 0;
int* ptr = b ? null_int_ptr : null_int_ptr;
Пример немного надуман, хотя: обычно, когда человек использует условного оператора, по крайней мере один из аргументов на самом деле является типом указателя (например, b ? ptr : 0
); Когда один из операндов является типом указателя, 0
неявно преобразуется в тот же тип указателя, и, следовательно, тип всего условного выражения является типом указателя, а не int
.
Единственный случай, когда вы можете иметь эту «проблему», - это то, где постоянная нулевого указателя используется как второй и третий операнды условного оператора, что довольно странно.
Другие советы
Ваша проблема в том, что в вашей системе NULL
определяется как 0
который предполагается, что является INT в контексте тройного оператора. если ты static_cast
один из операндов int*
Это должно автоматически производить другого.
Но почему в первую очередь используется такая конструкция?
NULL
можно определить как наличие типа int
или даже long
, Таким образом, тройной оператор имеет тот же тип. Там нет неявного преобразования в тип указателя, поэтому компилятор генерирует ошибку. Gotcha здесь заключается в том, что существует неявное преобразование из постоянной целочисленной экспрессии, оценивающей до нуля (печально известная постоянная нулевого указателя).
Возможное решение здесь - явный актерский состав:
int* ptr = b ? (int*) NULL : NULL;