11

In an answer there was the following code:

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

Which seems convenient, limiting the scope of the 'input' variable to where it's confirmed to be valid, however neither VS2015 nor g++ seems to compile it. Is it some compiler specific thing or does it require some extra flags?

In VS2015 the IDE highlights "std::ifstream" and the "input_file.txt" as well as the last parentheses. "std::ifstream" is flagged with "Error: a function type is not allowed here".

VS2015 C++ compiler gives following errors:

  • C4430 missing type specifier - int assumed. Note: C++ does not support default-int
  • C2059 syntax error: '('
Community
  • 1
  • 1
user3358771
  • 297
  • 2
  • 10

2 Answers2

15

The code you have is not legal.. yet. Prior to C++11 a if statement could be

if(condition)
if(type name = initializer)

and name would be evaluated as a bool to determine the condition. In C++11/14 the rules expended to allow

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

Where, again, name is evaluted as a bool after it is initialized to determine the condition.

Starting in C++17 though you will be able to declare a variable in a if statement as a compound statement like a for loop which allows you to initialize the variable with parentheses.

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

It should be noted though that this is just syntactic sugar and the above code is actually translated to

{
    std::ifstream input("input_file.txt")
    if (input.is_open())
    {
        // do stuff with input
    }
    else
    {
        // do other stuff with input
    }
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • 1
    You *can* declare a variable in a *condition* all the way back to C++03. It's just that the form of initialization is limited. – T.C. Apr 04 '17 at 19:26
  • @FredLarson Answr updated. I did have it wrong. Back in C++98/03 you could declare a variable. – NathanOliver Apr 04 '17 at 19:28
  • @NathanOliver Does it not also limit the scope of `input`? Or is it just sugar? – user3358771 Apr 04 '17 at 19:36
  • @NathanOliver: Update noted, answer upvoted, comment removed. – Fred Larson Apr 04 '17 at 19:36
  • @user3358771 All versions limit the scope. – NathanOliver Apr 04 '17 at 19:37
  • @NathanOliver Ah, yes.. Didn't notice the extra curlies in your last code earlier.. Your last two versions have the extra `is_open()`, is that necessary or? Mark B's answer seems to suggest that `(input_file.txt)` would not be legal even in C++17.. I guess what I'm asking is, is your last two versions using `is_open()` for the conditional because the `fstream input("...")` can't directly be used as the conditional? – user3358771 Apr 04 '17 at 19:41
  • @user3358771 The `is_open()` part is not really needed, I just put it there to show you can make it more complicated. Everywhere I have tried it with parentheses has worked and I am looking for the standardiess to confirm. – NathanOliver Apr 04 '17 at 19:44
  • @user3358771 Okay, `if (std::ifstream input("input_file.txt"))` is illegal period. `if (std::ifstream input("input_file.txt"); some_condition)` is legal C++17. – NathanOliver Apr 04 '17 at 19:52
  • Out of curiosity, do you know if ifstreams can be chained within the conditional while using the curlies? At least this fails: `if (std::ifstream ifs1{ "1.txt" } && std::ifstream ifs2{ "2.txt" })`. Putting them in separate if's of course works.. – user3358771 Apr 05 '17 at 22:17
  • @user3358771 From what I see in the standard it look like you can only declare a single variable. – NathanOliver Apr 06 '17 at 11:34
  • I think you will find the test is `!fail()`. Use a stream in a bool context causes `operator bool` to be called which in turn calls `!fail()`. Slightly different to `is_open()` – Martin York Apr 09 '17 at 16:03
8

According to http://en.cppreference.com/w/cpp/language/if that code is not legal (This site is pretty reputable but I can hunt for the standard reference if desired). You can declare variables in an if condition but they must be initialized by = or {}. So assuming you have at least C++11 you can do:

if (std::ifstream input{"input_file.txt"})
    ;
Mark B
  • 95,107
  • 10
  • 109
  • 188
  • 2
    OP's code is still not legal in C++17. The new *init-statement* feature doesn't change the required form of the *condition*. – T.C. Apr 04 '17 at 19:27