Определение fstream внутри "if" условного

В ответе появился следующий код:

if (std::ifstream input("input_file.txt"))
  ;

Это кажется удобным, ограничивая область "входной" переменной до того, где она подтверждается, что она действительна, однако ни VS2015, ни g++, похоже, ее не компилируют. Является ли это какой-то спецификой компилятора или требует каких-то дополнительных флагов?

В VS2015 IDE выделяет "std:: ifstream" и "input_file.txt", а также последние скобки. "std:: ifstream" помечен как "Ошибка: здесь не разрешен тип функции".

VS2015 Компилятор С++ дает следующие ошибки:

  • Спецификатор отсутствующего типа C4430 - int. Примечание: С++ не поддерживает default-int
  • Синтаксическая ошибка C2059: '('

Ответ 1

Код, который у вас есть, еще не закончен. До С++ 11 оператор if мог бы быть

if(condition)
if(type name = initializer)

и name будут оцениваться как bool для определения условия. В С++ 11/14 правила расходуются, чтобы разрешить

if(condition)
if(type name = initializer)
if(type name{initializer})

Если снова name вычисляется как bool после инициализации для определения условия.

Начиная с С++ 17, хотя вы сможете объявить переменную в выражении if как составной оператор, такой как цикл for, который позволяет инициализировать переменную с помощью круглых скобок.

if (std::ifstream input("input_file.txt"); input.is_open())
{
    // do stuff with input
}
else
{
    // do other stuff with input
}

Следует отметить, что это просто синтаксический сахар, и приведенный выше код фактически переведен на

{
    std::ifstream input("input_file.txt")
    if (input.is_open())
    {
        // do stuff with input
    }
    else
    {
        // do other stuff with input
    }
}

Ответ 2

В соответствии с http://en.cppreference.com/w/cpp/language/if этот код не является законным (этот сайт очень авторитетный, но я могу охотиться за стандартной ссылкой, если это необходимо), Вы можете объявлять переменные в условии if, но они должны быть инициализированы с помощью = или {}. Предположим, что вы имеете хотя бы С++ 11:

if (std::ifstream input{"input_file.txt"})
    ;