Я не собирался отвечать, но после публикации комментария я подумал, что ... это подход, как и любой другой:
int main() {
bool condition = true;
D1 d1;
D2 d2;
B * p = condition ? &d1 : (true? &d2 : p );
}
В основном злоупотребляют троичным оператором для извлечения соответствующего типа,Когда компилятор обрабатывает троичный оператор, он пытается определить, можно ли неявно преобразовать два операнда в общий тип 1 , и если это так, он использует этот общий тип в качестве типавыражение.
В приведенном выше коде внутренний троичный оператор: true? &d2 : p
попытается сопоставить тип выражения &d2
с типом p
, он обнаружит, что существует простойupcast, что он может выполнить и установит тип возврата для этого подвыражения равным B*
.Обратите внимание, что, поскольку условие true
, оно всегда будет выдавать &d2
, даже если для определения типа используется третий аргумент.
Та же операция выполняется с включающим выражением, где теперь второеаргумент &d1
(тип D1*
) и тип третьего аргумента B*
.Опять же, преобразование тривиально, выгрузив D1*
, и тип всего выражения: B*
.
Поскольку все преобразования выполняются неявно компилятором, если вы измените типы указателейи сломать инвариант, что они могут быть неявно преобразованы, компилятор скажет вам, решая проблему броска static_cast
в середине троичного оператора.
1 Стандартдиктует набор различных преобразований, в зависимости от типов аргументов.В частном случае, когда два аргумента являются указателями (как в данном случае), допустимыми являются преобразования преобразования указателей и преобразования квалификации .