This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-12-19


2800. Instantiating constexpr variables for potential constant evaluation

Section: 7.7  [expr.const]     Status: review     Submitter: Shafik Yaghmour     Date: 2023-09-22

Consider:

  template <typename T>
  struct A {
    T data;

    static const A a;
  };
  template <typename T>
  inline constexpr A<T> A<T>::a {42};

  static_assert(A<int>::a.data == 42);

This ought to be well-formed, but there is no rule that would cause instantiation of A<int>::a.

Also consider:

  template<typename T> struct A {
    static T x;
  };
  template<typename T> T A<T>::x = (std::cout << "constructed", T());
  template<typename T> void b(decltype(&A<int>::x));

For the second example, it is undesirable to instantiate A<int>.

Possible resolution [SUPERSEDED]:

Change in 7.7 [expr.const] paragraph 3 as follows:

A variable is potentially-constant if it is constexpr or it has reference or non-volatile const-qualified integral or enumeration type or, for a templated variable, if the definition that would be instantiated if the variable were needed for constant evaluation uses the constexpr decl-specifier (13.7.6.2 [temp.spec.partial.match]).

CWG 2023-10-20

The phrasing suggests that const int variables instantiated from a variable template are no longer potentially-constant.

Possible resolution:

Change in 7.7 [expr.const] paragraph 3 as follows:

A variable is potentially-constant if it is constexpr declared with the constexpr decl-specifier or it has reference or non-volatile const-qualified integral or enumeration type. Such a variable may be instantiated from a templated variable, in which case the definition that would be instantiated if the variable were needed for constant evaluation is considered (13.7.6.2 [temp.spec.partial.match]).