ISO/IEC JTC1 SC22 WG21 P1907R1
Jens Maurer <>
Target audience: EWG, CWG

P1907R1: Inconsistencies with non-type template parameters


Non-type template parameters were originally limited to having scalar non-floating-point types. Through a number of recent changes, non-type template parameters of class type are now supported as well, provided they have strong structural equality, in particular no user-defined operator== for any of the class's subobjects. P1714R1 (NTTP are incomplete without float, double, and long double!), which added floating-point types as permissible non-type template parameters (with bit-wise comparison on the value representation), was rejected by plenary straw poll in Cologne.

The following wording implements guidance by EWG in Belfast to address the following NB comments:



Remove 11.11.1 [] paragraph 4:
A type C has strong structural equality if, given a glvalue x of type const C, either:
Change in 13.2 [temp.param] paragraph 4:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types: [Note: Other types are disallowed either explicitly below or implicitly by the rules governing the form of template-arguments (13.4 [temp.arg]). ā€” end note] The top-level cv-qualifiers on the template-parameter are ignored when determining its type.
Change in 13.4.2 [temp.arg.nontype] paragraph 2:
A template-argument for a non-type template-parameter shall be a converted constant expression (7.7) of the type of the template-parameter . For a non-type template-parameter of reference or pointer type, or for each non-static data member of reference or pointer type in a non-type template-parameter of class type or subobject thereof, the reference or pointer value shall not refer to or be the address of (respectively):
A structural type is one of the following:
Change in 13.2 [temp.param] paragraph 6:
An id-expression naming a non-type template-parameter of class type T denotes a static storage duration object of type const T, known as a template parameter object, whose value is that of the corresponding template argument after it has been converted to the type of the template-parameter. All such template parameters in the program of the same type with the same value denote the same template parameter object. A template parameter object shall have constant destruction (7.7 [expr.const]). [Note: If an id-expression names a non-type non-reference template-parameter, then it is a prvalue if it has non-class type. Otherwise, if it is of class type T, it is an lvalue and has type const T ( ā€” end note] [Example:
Change in 13.6 [temp.type] paragraph 1:
Two template-ids refer to the same class, function, or variable if
Two values are template-argument-equivalent if they are of the same type and