passing function template prototype as argument

Viewed 89

I am trying to pass a templated function to another, like this:

template<typename T = bool>
void fun() {}

template<typename F>
void higher_order_fun( const F & f) {
    f();
}

int main () {
    //higher_order_fun(fun<>); //works
    higher_order_fun(fun);
}

In gcc10.2 I am able to pass fun (a template prototype) in the same way as the specified type fun<>.
Note that this does not work if I don't have the default template parameter T=bool.

In Clang11 this doesn't work.
See https://godbolt.org/z/9WfMdc.

What is going on here?

2 Answers

All standard references below refer to N4659: March 2017 post-Kona working draft/C++17 DIS.


This is arguably a GCC bug (/extension feature), although I have not been able to find a ticket for it.

As per [temp.names]/1, you may refer to a template specialization by means of a template-id. The grammar for the latter does not allow omission of the the angle brackets <>, even if the template-argument-list within it may be empty (opt):

A template specialization can be referred to by a template-id:

simple-template-id:
  template-name < template-argument-list_opt >

template-id:
  simple-template-id
  operator-function-id < template-argument-list_opt >
  literal-operator-id < template-argument-list_opt >

In your case, you want to refer to the specialization fun<bool> of the function template fun, which is the same specialization you can refer to by making use of the default template argument for the single type template argument of fun, namely as fun<>. You cannot, however, refer to the fun<bool> specialization only by specifying fun; the latter does not refer to a specialization, and thus, your program is ill-formed.

You need to specify what is T when you pass fun because you need an instantiation of that parameter to build that function. Compiler needs to infer T somehow.

Compiler assumes that T is of class bool with fun or fun<>, but you cannot get rid of the default template parameter or it will not be able to deduce it.

Related