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

2024-11-11


88. Specialization of member constant templates

Section: 13.9.4  [temp.expl.spec]     Status: NAD     Submitter: Jason Merrill     Date: 20 Jan 1999

Is this valid C++? The question is whether a member constant can be specialized. My inclination is to say no.

    template <class T> struct A {
        static const T i = 0;
    };

    template<> const int A<int>::i = 42;

    int main () {
        return A<int>::i;
    }
John Spicer: This is ill-formed because 11.4.9.3 [class.static.data] paragraph 4 prohibits an initializer on a definition of a static data member for which an initializer was provided in the class.

The program would be valid if the initializer were removed from the specialization.

Daveed Vandevoorde: Or at least, the specialized member should not be allowed in constant-expressions.

Bill Gibbons: Alternatively, the use of a member constant within the definition could be treated the same as the use of "sizeof(member class)". For example:

    template <class T> struct A {
        static const T i = 1;
        struct B { char b[100]; };
        char x[sizeof(B)];     // specialization can affect array size
        char y[i];             // specialization can affect array size
    };

    template<> const int A<int>::i = 42;
    template<> struct A<int>::B { char z[200] };

    int main () {
        A<int> a;
        return sizeof(a.x)   // 200  (unspecialized value is 100)
             + sizeof(a.y);  // 42   (unspecialized value is 1)
    }
For the member template case, the array size "sizeof(B)" cannot be evaluated until the template is instantiated because B might be specialized. Similarly, the array size "i" cannot be evaluated until the template is instantiated.

Rationale (10/99): The Standard is already sufficiently clear on this question.