Прямая инициализация объекта внутри условия
Можно определить и скопировать инициализацию переменной внутри условия оператора if
:
if(int i = 17) { ... }
Это также работает с пользовательскими типами, учитывая, что они перегружают operator bool
:
if(Foo f = 42) { ... }
if(Foo f = Foo(43)) { ... }
Почему я не могу использовать прямую инициализацию, например следующее:
if(Foo f(51)) { ... }
GCC испускает error: expected primary-expression before 'f'
.
Live on Coliru
Есть ли причина, кроме "потому что грамматика говорит так"? И как я могу обойти это?
Я работаю с VС++ 03, где Foo
:
- - это объект, чувствительный к RAII, для которого я позаботился о том, чтобы не определять конструктор копирования
- - это шаблон, принимающий аргументы пользователя
- имеет конструктор с двумя параметрами
... поэтому я бы предпочел не копировать его или не повторять его тип.
Примечание. Хотя моя фактическая проблема связана с С++ 03, я (академически) интересуюсь ответами на С++ 11.
Ответы
Ответ 1
В С++ 03 можно использовать синтаксис только для копирования:
selection-statement:
if (
условие )
statement [...]
условие: выражение type-specifier-seq declarator =
Назначение выражение
С С++ 11 была добавлена инициализация списка:
условие:
выражение
атрибут-specifier-seq opt decl-specifier-seq declarator =
initializer-clause
атрибут-specifier-seq opt decl-specifier-seq declarator приготовился-INIT-лист
Синтаксис прямой инициализации, т.е. Foo f(…)
, по-видимому, был исключен по той же причине, что и для нестатических инициализаторов элементов данных, это было запрещено: неоднозначность, в частности "самый неприятный синтаксический анализ".
Ответ 2
Поскольку стандарт С++ 03 разрешает инициализацию присваивания внутри условий:
condition:
expression
type-specifier-seq declarator = assignment-expression
Ответ 3
Учитывая ваши ограничения, я верю в С++ 03, ваш единственный вариант - объявить переменную вне инструкции if
, добавив фигурные скобки для определения области видимости:
{
Foo f(51, 52);
if (f) {
//...
}
}
В С++ 11 вы можете использовать синтаксис синтаксиса:
if (Foo f{51, 52}) {
//...
}