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

2024-04-18


354. Null as nontype template argument

Section: 13.4.3  [temp.arg.nontype]     Status: CD1     Submitter: John Spicer     Date: 2 May 2002

[Voted into WP at October 2005 meeting.]

The standard does not permit a null value to be used as a nontype template argument for a nontype template parameter that is a pointer.

This code is accepted by EDG, Microsoft, Borland and Cfront, but rejected by g++ and Sun:

  template <int *p> struct A {};
  A<(int*)0> ai;

I'm not sure this was ever explicitly considered by the committee. Is there any reason to permit this kind of usage?

Jason Merrill: I suppose it might be useful for a program to be able to express a degenerate case using a null template argument. I think allowing it would be harmless.

Notes from October 2004 meeting:

CWG decided that it would be desirable to allow null pointers as nontype template arguments, even though they are not representable in some current ABIs. There was some discussion over whether to allow a bare 0 to be used with a pointer nontype template parameter. The following case was decisive:

    template<int i> void foo();
    template<int* i> void foo();
    ...
    foo<0>();

The current wording of 13.4 [temp.arg] paragraph 7 disambiguates the function call in favor of the int version. If the null pointer conversion were allowed for pointer nontype template parameters, this case would become ambiguous, so it was decided to require a cast.

Proposed resolution (April, 2005):

  1. In 13.4.3 [temp.arg.nontype] paragraph 1, insert the following after the third bullet:

  2. Add the indicated text to the note in the second bullet of 13.4.3 [temp.arg.nontype] paragraph 5:

    [Note: In particular, neither the null pointer conversion (7.3.12 [conv.ptr]) nor the derived-to-base conversion (7.3.12 [conv.ptr]) are applied. Although 0 is a valid template-argument for a non-type template-parameter of integral type, it is not a valid template-argument for a non-type template-parameter of pointer type. However, (int*)0 is a valid template-argument for a non-type template-parameter of type “pointer to int.”end note]
  3. Replace the normative wording of 13.6 [temp.type] paragraph 1 with the following:

    Two template-ids refer to the same class or function if

    • their template-names refer to the same template, and
    • their corresponding type template-arguments are the same type, and
    • their corresponding non-type template-arguments of integral or enumeration type have identical values, and
    • their corresponding non-type template-arguments of pointer type refer to the same external object or function or are both the null pointer value, and
    • their corresponding non-type template-arguments of pointer-to-member type refer to the same class member or are both the null member pointer value, and
    • their corresponding non-type template-argumentss for template parameters of reference type refer to the same external object or function, and
    • their corresponding template template-arguments refer to the same template.