Construction of temporary in function call is interpreted as declaration

前端 未结 2 1777
慢半拍i
慢半拍i 2020-12-20 16:18

Lately I ran into a problem which somehow (but only somehow) makes sense to me. It is based on interpreting the construction of a temporary as declaration of the single (!)

相关标签:
2条回答
  • 2020-12-20 16:50

    1) Foo0(x) is treated as a parameter of function bar0 in this instance. Here, it does not matter if it has a standard constructor or not. It's not a local variable declaration and initialization, but just a parameter declaration in a function declaration.

    2) My guess is this has something to do with the parsing, but somebody correct me if I'm wrong.. Examples bar1 and bar2 work, because the compiler knows that bar1 and bar2 are local variable declarations (and not function declarations) as soon as it sees the first occurrence of {}. These first occurences of {} appear before x is declared twice as a parameter of the function.

    3) The construction of bar3 fails, because the compiler first assumes that bar3 is a function declaration. The function declaration takes three parameters, which are all named x. Obviously, this is not correct.

    4) The x in the function declaration is just a name for the parameter. It is in a different scope than the integer x you declared before that.

    0 讨论(0)
  • 2020-12-20 16:53

    The rule is that if a declaration has the syntax of a function declaration then it is one; otherwise it is a variable declaration. Surprising instances of this are sometimes called most-vexing-parse.

    Bar bar0(Foo0(x), Foo1(x), Foo2(x)); // Does not work: conflicting declaration ‘Foo1 x’ previous declaration as ‘Foo0 x’; conflicting declaration ‘Foo2 x’ previous declaration as ‘Foo0 x’
    

    This is a function declaration: bar0 is the name, Bar is the return type, and the parameter types are Foo0, Foo1 and Foo2. The parameter names are all x which is illegal - the names of function parameters must be different. If you change x x x to x y z the error goes away).

    Bar bar1(Foo0{x}, Foo1(x), Foo2(x)); // Works WTF
    Bar bar2(Foo0(x), Foo1{x}, Foo2(x)); // Works WTF
    Bar bar4(Foo0{x}, Foo1{x}, Foo2{x}); // Works totally makes sens to me
    

    These lines and create objects bar1, bar2, and bar4 of type Bar. They cannot be parsed as function declarations because the { } notation is not valid syntax in a function declaration.

    Therefore, Foo0{x} etc. are expressions which provide the arguments to Bar's constructor. Foo0{x} and Foo0(x) are equivalent ways of declaring a temporary of type Foo0 with initializer x.

    Bar bar3(Foo0(x), Foo1(x), Foo2{x}); // Does not work: conflicting declaration ‘Foo1 x’ previous declaration as ‘Foo0 x’
    

    I think this is a compiler bug; the part Foo2{x} means that this line cannot be a function declaration; and it looks like a valid declaration of a variable bar3.

    x.doStuff(); //Dose not work. This makes sens to me. But in the context its curious
    

    x is an int ; it does not have any methods.

    0 讨论(0)
提交回复
热议问题