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

2024-03-20


2106. Unclear restrictions on use of function-type template arguments

Section: 13.4.2  [temp.arg.type]     Status: CD4     Submitter: David Krauss     Date: 2015-03-17

[Adopted at the February, 2016 meeting.]

According to 13.4.2 [temp.arg.type] paragraph 3,

If a declaration acquires a function type through a type dependent on a template-parameter and this causes a declaration that does not use the syntactic form of a function declarator to have function type, the program is ill-formed.

This is not clear enough regarding which declarations are in view. For example, does it apply to a typedef declaration? Does it apply to a parameter declaration, where normal function-to-pointer decay would apply? There is implementation variance at block scope.

Also, since this applies a restriction to the usage of dependent types, not template type arguments per se, the paragraph presumably should appear in 13.8.3.2 [temp.dep.type] and not its current location.

Proposed resolution (September, 2015):

  1. Delete 13.4.2 [temp.arg.type] paragraph 3:

  2. If a declaration acquires a function type through a type dependent on a template-parameter and this causes a declaration that does not use the syntactic form of a function declarator to have function type, the program is ill-formed. [Example:

      template<class T> struct A {
        static T t;
      };
      typedef int function();
      A<function> a; // ill-formed: would declare A<function>::t
                     // as a static member function
    

    end example]

  3. Add the following as a new paragraph following 13.9 [temp.spec] paragraph 6:
  4. ...X<int> has a static member s of type int and X<char*> has a static member s of type char*. —end example]

    If a function declaration acquired its function type through a dependent type (13.8.3.2 [temp.dep.type]) without using the syntactic form of a function declaator, the program is ill-formed. [Example:

       template<class T> struct A {
         static T t;
       };
       typedef int function();
       A<function> a;   // ill-formed: would declare A<function>::t
                        // as a static member function
    

    end example]