[expr.prim.splice] (original) (raw)
7 Expressions [expr]
7.5 Primary expressions [expr.prim]
7.5.9 Expression splicing [expr.prim.splice]
[Example 1: struct S { static constexpr int a = 1; };template<typename> struct TCls { static constexpr int b = 2; };constexpr int c = [:^^S:]::a; constexpr int d = template [:^^TCls:]<int>::b; template<auto V> constexpr int e = [:V:]; constexpr int f = template [:^^e:]<^^S::a>; constexpr auto g = typename [:^^int:](42); constexpr auto h = ^^g;constexpr auto i = e<[:^^h:]>; constexpr auto j = e<([:^^h:])>; — _end example_]
- The expression is ill-formed if S is
- a constructor,
- a destructor,
- an unnamed bit-field, or
- a local entity ([basic.pre]) such that
* there is a lambda scope that intervenes between the expression and the point at which S was introduced and
* the expression would be potentially evaluated if the effect of any enclosing typeid expressions ([expr.typeid]) were ignored.
- Otherwise, if S is a function F, the expression denotes an overload set containing all declarations of Fthat precede either the expression or the point immediately following the class-specifier of the outermost class for which the expression is in a complete-class context; overload resolution is performed ([over.match], [over.over]).
- Otherwise, if S is an object or a non-static data member, the expression is an lvalue designating S.
The expression has the same type as that of S, and is a bit-field if and only if S is a bit-field.
[Note 1:
The implicit transformation whereby an id-expression denoting a non-static member becomes a class member access ([expr.prim.id]) does not apply to a splice-expression.
— _end note_] - Otherwise, if S is a variable or a structured binding,S shall either have static or thread storage duration or shall inhabit a scope enclosing the expression.
The expression is an lvalue referring to the object or function Xassociated with or referenced by S, has the same type as that of S, and is a bit-field if and only if X is a bit-field.
[Note 2:
The type of a splice-expressiondesignating a variable or structured binding of reference type will be adjusted to a non-reference type ([expr.type]).
— _end note_] - Otherwise, if S is a value or an enumerator, the expression is a prvalue that computes S and whose type is the same as that of S.
- Otherwise, the expression is ill-formed.
For a splice-expression of the form template splice-specifier, the splice-specifier shall designate a function template Tthat is not a constructor template.
The expression denotes an overload set containing all declarations of Tthat precede either the expression or the point immediately following the class-specifier of the outermost class for which the expression is in a complete-class context; overload resolution is performed.
[Note 3:
During overload resolution, candidate function templates undergo template argument deduction and the resulting specializations are considered as candidate functions.
— _end note_]
- If T is a function template, the expression denotes an overload set containing all declarations of Tthat precede either the expression or the point immediately following the class-specifier of the outermost class for which the expression is in a complete-class context; overload resolution is performed ([over.match], [over.over]).
- Otherwise, if T is a variable template, let S be the specialization of T corresponding to the template argument list of the splice-specialization-specifier.
The expression is an lvalue referring to the object associated with S and has the same type as that of S. - Otherwise, the expression is ill-formed.
[Note 4:
Class members are accessible from any point when designated by splice-expressions ([class.access.base]).
A class member access expression ([expr.ref]) whose right operand is a splice-expression is ill-formed if the left operand (considered as a pointer) cannot be implicitly converted to a pointer to the designating class of the right operand.
— _end note_]