This paragraph from the C++ 17 standard draft states, among others, that:
A full-expression is:
-an unevaluated operand,
-a constant-expression ([expr.const]),
-an init-declarator ([dcl.decl]) or a mem-initializer ([class.base.init]), including the constituent expressions of the initializer,
-an invocation of a destructor generated at the end of the lifetime of an object other than a temporary object, or
-an expression that is not a subexpression of another expression and that is not otherwise part of a full-expression.
If a language construct is defined to produce an implicit call of a function, a use of the language construct is considered to be an expression for the purposes of this definition. [...]
struct S { S(int i): I(i) { } // full-expression is initialization of I int& v() { return I; } ~S() noexcept(false) { } private: int I; }; S s1(1); // **full-expression is call of S::S(int)**
For the rest of this post I will refer to a "language construct defined to produce an implicit call of a function" simply as "construct".
I have several questions related to the quoted paragraph:
Why is this passage ("and that is not otherwise part of a full-expression") mentioned? The only reasons I can think of are: a "construct" containing an expression (true expression, not the definition used in this paragraph, which considers "constructs" as expressions) that, otherwise, would be regarded as a full-expression or a "construct" containing another "construct", which, similarly, on its own would be considered as a full-expression. Are these reasons correct? If so, I would appreciate some concrete examples.
What are some examples of "constructs"? I know that the initialization of an object could be one (because of the implicit call to the constructor), but the third dot of the paragraph ("an init-declarator ([dcl.decl])) explicitly considers it as a full-expression. Also, using the new operator means implicitly calling two functions (one for allocating the space and afterwards the constructor), but a new expression is an expression on its own.
Why for the construct: "S s1(1)" is it said that the full-expression is the call to the constructor "S::S(int)"? Why isn't the full-expression the construct itself?
B b[2] = { B(), B() }; // full-expression is the entire initialization including the destruction of temporaries
. I think that phrase refers to this case. You have init-declarator that's not, technically, an expression, and so parts of it are not, technically, subexpressions. – HindiS s1(1), s2(2);
to represent two full expressions. – HindiS s1(1), s2(2);
represents an entire construct (real meaning, not the one used in this question), but it does not require an implicit function call, because the implicit function calls are made by its sub-constructs:S s1(1)
and(S) s2(2)
? Therefore the outer construct is not a full-expression, but the inner constructs are? Is this one way to interpret it? – Expositions1(1)
ands2(2)
are init-declarators within the meaning of [dcl.decl]. They are therefore full expressions, per the third bullet of the paragraph you cite. They are not, however, expressions within the meaning of [expr] (1
and2
are; but they are not full-exressions because they are "otherwise part of a full-expression"). – HindiS s1(1)
is the call toS::S(int)
is a contradiction. The paragraph says that a "construct" is to be considered as an expression in this context. Furthermore, this construct is not part of an outer full-expression, therefore, in my opinion, the entire construct should be considered as the full-expression. Maybe it underlines the implicit function call. – Exposition