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

2024-10-26


1584. Deducing function types from cv-qualified types

Section: 13.10.3.2  [temp.deduct.call]     Status: drafting     Submitter: Daniel Krügler     Date: 2012-11-04

It is not clear whether the following is well-formed or not:

  void foo(){}

  template<class T>
  void deduce(const T*) { }

  int main() {
    deduce(foo);
  }

Implementations vary in their treatment of this example.

Proposed resolution (April, 2013):

Change 13.10.3.6 [temp.deduct.type] paragraph 18 as follows:

A template-argument can be deduced from a function, pointer to function, or pointer to member function type. [Note: cv-qualification of a deduced function type is ignored; see 9.3.4.6 [dcl.fct]. —end note] [Example:

  template<class T> void f(void(*)(T,int));
  template<class T> void f2(const T*);
  template<class T> void foo(T,int);
  void g(int,int);
  void g(char,int);
  void g2();

  void h(int,int,int);
  void h(char,int);
  int m() {
    f(&g);     // error: ambiguous
    f(&h);     // OK: void h(char,int) is a unique match
    f(&foo);   // error: type deduction fails because foo is a template
    f2(g2);    // OK: cv-qualification of deduced function type ignored
  }

end example]

Additional note, November, 2014:

Concern was expressed regarding the proposed resolution over its treatment of an example like the following:

  template<typename T> struct tuple_size {};
  template<typename T> struct tuple_size<T const>: tuple_size<T> {};

  tuple_size<void()> t;

In this case T const is always considered to be more specialized for void(), leading to infinite self-derivation.

The issue has been returned to "open" status for further consideration.

Notes from the May, 2015 meeting:

The consensus of CWG was that the cv-qualification of the argument and parameter must match, so the original example should be rejected.