Type agreement of non-type template arguments in partial specializations
_N4868_.13.7.6 [temp.class.spec]
John Spicer

Created on 2013-04-04.00:00:00 last changed 97 months ago


Date: 2021-02-24.00:00:00

The Standard appears to be silent on whether the types of non-type template arguments in a partial specialization must be the same as those of the primary template or whether conversions are permitted. For example,

  template<char...> struct char_values {};
  template<int C1, char C3>
  struct char_values<C1, 12, C3> {
    static const unsigned value = 1;
  int check0[char_values<1, 12, 3>::value == 1? 1 : -1]; 

The closest the current wording comes to dealing with this question is _N4868_.13.7.6 [temp.class.spec] paragraph 8 bullet 1:

  • A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier.

In this example, one might think of the first template argument in the partial specialization as (char)C1, which would violate the requirement, but that reasoning is tenuous.

It would be reasonable to require the types to match in cases like this. If this kind of usage is allowed it could get messy if the primary template were int... and the partial specialization had a parameter that was char because not all of the possible values from the primary template could be represented in the parameter of the partial specialization. A similar issue exists if the primary template takes signed char and the partial specialization takes unsigned int.

There is implementation variance in the treatment of this example.

(See also issues 1315, 2033, and 2127.)

Date User Action Args
2013-04-04 00:00:00admincreate