A code snippet from cppreference.com is like this:
struct M { };
struct L { L(M&); };
M n;
void f() {
M(m); // declaration, equivalent to M m;
L(n); // ill-formed declaration
L(l)(m); // still a declaration
}
L(n);
is commented with "ill-formed declaration".
But nearly all compilers issue message like this: no default constructor exists for class "L". That is to say, it's not considered to be ill-formed, right? Because if i throw a line L() = default;
into L's body, it compiles successfully.
Is the comment wrong or misleading or compilers are not strictly standard-conforming?
Follow Up
Seems that i made something wrong with ill-formed:
ill-formed - the program has syntax errors or diagnosable semantic errors. A conforming C++ compiler is required to issue a diagnostic, > even if it defines a language extension that assigns meaning to such > code (such as with variable-length arrays). The text of the standard > uses shall, shall not, and ill-formed to indicate these requirements.
In light of that, that line is semantically wrong.
Thanks, for you guys' answers and comments.
I think that the example demonstrates that declarator may be enclosed in parentheses.
So this declaration
M(m);
is equivalent to
M m;
that is there is declared an object m
of the type M
.
However this record
L(n);
can be considered as an expression statement with calling the constructor L( M & )
with the argument n
of the type M
or as a declaration.
The C++ Standard resolves such an ambiguity as a declaration instead of the expression statement. So in this record n
is the name of the created object. But the class L
does not have the default constructor. So the declaration is ill-formed because the structure L
does not have the default constructor that is required for this declaration.
From the C++ 14 Standard (6.8 Ambiguity resolution)
1 There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.
To make an expression statement instead of the declaration you can write for example
( L )( n );
This record
L(l)(m);
is a correct declaration. There is declared the object l
of the type L using the constructor L( M & )
.