Is it a defect about a non-type template parameter of a reference type that there are no special rules permit it to be used in a constant expression

Viewed 214

Consider this example:

template<int const& rf>
struct A{
  void fun(){
    constexpr int v = rf;  //#1
  }
};
int const object = 0;
int main(){
   A<object> a;
   a.fun();
}

GCC and Clang both agree that rf can be used as a constant expression.

However, in this case, rf is an id-expression. Hence, only the id-expression satisfies the following rule can it be used in a constant expression. The relevant rule is:
[expr.const#5.12]

an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either

  • it is usable in constant expressions or
  • its lifetime began within the evaluation of E;

For the id-expression rf at #1, its lifetime does not begin within the evaluation of initialization. So, bullet 2 is not satisfied here. At the view of the declaration constexpr int v = rf; where id-expression rf does not have a preceding initialization. For bullet 1, the relevant rule says:

A constant-initialized potentially-constant variable V is usable in constant expressions at a point P if V's initializing declaration D is reachable from P and

  • V is constexpr
  • V is not initialized to a TU-local value, or
  • P is in the same translation unit as D.

rf is not constant-initialized since it neither has an initializer nor its default-initialization results in some initialization being performed. So, the id-expression rf used in #1 will violate [expr.const#5.12]. Hence, it cannot be used in #1. Actually, all compilers agree rf can be used in constant-expression(it also conforms to intuitive). However, the rule in the standard conflicts here. How to interpret this? Does it lack wording for a non-type template parameter that can be used in a constant expression?

0 Answers
Related