3

Consider the code:

#include <iostream>

struct Foo
{
    Foo(int){}
    operator bool() const
    {
        return true;
    }
};

int main()
{
    if(Foo foo{42})
    {
        std::cout << "ok\n";
    }
}

It compiles fine under gcc5. However, if I replace the line if(Foo foo{42}) with

if(Foo foo(42))

I get a compile-time error:

error: expected primary-expression before 'foo'

What's going on here? There is no vexing parse imo, so why using braces work?

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • @Niall Yes, that's why I asked the question, before that answer appeared there. I should probably close it now as a dupe and link to that question. – vsoftco Feb 15 '16 at 13:58
  • I think a broader question is why is was not included to begin with. It may have been some compatibility issue, also not sure how it could be tied to the vexing parse; but I was somewhat surprised to was not allowed. Goes to show how little I ever initialize variables in the condition statement... – Niall Feb 15 '16 at 18:19

1 Answers1

6

The syntax for a condition does not include classic constructor invocation.

C++11 §6.4/1:

condition:
    expression
    attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
    attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list

This is used in if, switch, while and do. I was surprised to now discover that it's used in switch. I never thought of that as a condition.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 1
    With C++11, this looks like a small defect imo. Why would we be allowed to use `Foo foo{42}` but not `Foo foo(42)`? There are no parsing issues here. – vsoftco Feb 15 '16 at 14:02
  • Maybe to ease parsing? Having variable declarations in conditions is already a special case and parentheses are overloaded enough as it is. – TartanLlama Feb 15 '16 at 14:07