Вопрос

Я знаю, что у тройного оператора есть некоторые удивительные ограничения, но я был немного сбит с толку, что это не может составить для меня:

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 с NULLS, чтобы проверить, если 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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top