7 Expressions [expr]

7.5 Primary expressions [expr.prim]

7.5.9 Expression splicing [expr.prim.splice]

A splice-specifier or splice-specialization-specifier immediately followed by ​::​ or preceded by typename is never interpreted as part of a splice-expression.
[Example 1: struct S { static constexpr int a = 1; }; template<typename> struct TCls { static constexpr int b = 2; }; constexpr int c = [:^^S:]::a; // OK, [:^^S:] is not an expression constexpr int d = template [:^^TCls:]<int>::b; // OK, template [:^^TCls:]<int> is not an expression template<auto V> constexpr int e = [:V:]; // OK constexpr int f = template [:^^e:]<^^S::a>; // OK constexpr auto g = typename [:^^int:](42); // OK, typename [:^^int:] is a splice-type-specifier constexpr auto h = ^^g; constexpr auto i = e<[:^^h:]>; // error: unparenthesized splice-expression used as template argument constexpr auto j = e<([:^^h:])>; // OK — end example]
For a splice-expression of the form splice-specifier, let S be the construct designated by splice-specifier.
  • 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 F that 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 X associated 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-expression designating 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 T that is not a constructor template.
The expression denotes an overload set containing all declarations of T that 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]
For a splice-expression of the form template splice-specialization-specifier, the splice-specifier of the splice-specialization-specifier shall designate a template T.
  • If T is a function template, the expression denotes an overload set containing all declarations of T that 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]