Это формально правильно (в C ++, но не в C).Разрешение определения в качестве условия было добавлено с dynamic_cast
для поддержки таких вещей, как:
if ( Derived* p = dynamic_cast<Derived*>( ptrToBase ) ) {
// ...
}
Аргумент состоял в том, что никогда не будет момента, когда p
находится в области действия
,ненулевой.После if
, p
больше не находится в области видимости.
Аргумент не содержит воды, поскольку, с одной стороны, если вы добавите else
в блоке else
, p
находится в области видимости, и ноль.И оправдание, связанное с ограничением области действия, на самом деле не очень сильное, потому что, если функция достаточно длинная, чтобы она имела значение, она слишком длинная и слишком сложная.Эта конструкция поддерживает такие вещи, как:
if ( Derived1* p = dynamic_cast<Derived1*>( ptrToBase ) ) {
// ...
}
if ( Derived2* p = dynamic_cast<Derived2*>( ptrToBase ) ) {
// ...
}
// ...
Но на самом деле это не то, что вы хотите сделать в хорошем коде.
В общем, я бы избежал конструкции, заменив ее начто-то вроде:
int* p2 = p;
if ( p2 != NULL ) {
// ...
}
Это более явно и более читабельно.Это означает, что p2
находится вне области действия if
, но я бы сказал, что если это вызывает какие-либо проблемы, сама функция требует рефакторинга, потому что она слишком длинная и слишком сложная.
EDIT:
Что касается предупреждения: это полный идиотизм со стороны компилятора.В условном выражении нет присваивания: нет присваивания, точки и нет «условного выражения», условие в оригинале - это объявление, а не выражение. Если компилятор хочет что-то предупредить (по стилистическим соображениям, поскольку он согласен со мной, что это плохой стиль), то он должен предупредить о неявном преобразовании в bool
.(И, конечно, то, должно ли быть выдано это предупреждение, должно контролироваться опцией. Компилятор должен компилировать язык, а не навязывать стиль, если только один не попросит его явно предупредить о конкретных проблемах стиля.)