Search code examples
c++functiontemplatesfunctor

Why can't template functions be passed as a template template parameter?


When i am trying to pass a function as a template template type parameter to a class, error encountered. Why language core developers won't enable this ability? Functor class templates could be passed, but function templates can't.

For example, compiling this code in "g++ (Ubuntu 8.3.0-6ubuntu1) 8.3.0":

#include <iostream>

using namespace std;

template <template <typename> typename Functor>
class UseFunc
{
public:
    void use()
    {
        Functor<int>(3);
        Functor<char>('s');
    }
};

template <typename T>
void func(T s)
{
    cout << s << endl;
}

int main()
{
    UseFunc<func> u {};
    u.use();
}

tells:

kek.cpp: In function ‘int main()’:                                                                                                           
kek.cpp:24:14: error: type/value mismatch at argument 1 in template parameter list for ‘template<template<class> class Functor> class UseFunc’
  UseFunc<func> u {};                                                                                                                        
              ^                                                                                                                              
kek.cpp:24:14: note:   expected a class template, got ‘func’                                                                                 
kek.cpp:25:4: error: request for member ‘use’ in ‘u’, which is of non-class type ‘int’                                                       
  u.use();                                                                                                                                   
    ^~~   

I expected it to be implemented the same way as template template parameter passing is. At the end of the day it is just a request to compiler, so that functions of concrete types could be instantiated and used in a usual way.

Truly don't understand this limitation and it would be great if someone could tell me what is the difficulty of implementing this.


Solution

  • I don't know for sure the answer to the question of why C++ does not provide function template template parameters, but I imagine it has something to do with:

    • Any nontrivial change to templates will require complicated analysis to determine what changes need to be made to the standard text
    • This feature would be rarely used; after all, class template template parameters are mostly used in partial specializations, i.e., to dispatch on types that are themselves template specializations, and it's rare to want to do that with functions
    • It wouldn't make sense to support function template template parameters without also supporting a type of template parameter that would accept any non-template function (we can do this in C++17 with auto but this is obviously way too late for C++98 to have function template template parameters)
    • You can work around the lack of function template template parameters using class templates anyway (sort of like what we do with partial specializations).
    • Function overloading complicates things. In the presence of overloading, there's no way to unambiguously name a particular function template. Should one be provided? Or, do we take the point of view that an overload set is meant to be passed as a whole to a function template template parameter? What if overload resolution then selects a non-template overload? How do we even answer these design questions without having a compelling use case?

    If you believe that you know how to address all these concerns, and in particular can provide a compelling argument for why we need this feature in the language despite the fact that it would be complicated and we can work around its absence using class template template parameters, feel free to write up a proposal for the standard.