为什么不能将模板函数作为模板模板参数传递?

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

当我尝试将函数作为模板模板类型参数传递给 class 时,遇到错误。为什么语言核心开发人员不启用此功能? Functor class 模板可以传递,但函数模板不能。

例如,在"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();
}

讲述:

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();                                                                                                                                   
    ^~~   

我希望它的实现方式与模板模板参数传递方式相同。归根结底,这只是对编译器的一个请求,以便可以以通常的方式实例化和使用具体类型的函数。

真的不明白这个限制,如果有人能告诉我实现这个的困难是什么,那就太好了。

我不确定为什么 C++ 不提供函数模板模板参数的问题的答案,但我想它与以下问题有关:

  • 对模板的任何重要更改都需要进行复杂的分析,以确定需要对标准文本进行哪些更改
  • 这个功能应该很少用到;毕竟,class 模板模板参数主要用于偏特化, 即, 用于分派本身就是模板特化的类型,并且很少想用函数来做到这一点
  • 如果不支持接受任何 non-template 函数的模板参数类型,则支持函数模板模板参数是没有意义的(我们可以这样做在 C++17 中使用 auto 但这对于 C++98 具有函数模板模板参数来说显然太晚了)
  • 无论如何,您都可以使用 class 模板解决缺少函数模板模板参数的问题(有点像我们对偏特化所做的)。
  • 函数重载使事情复杂化。在重载的情况下,没有办法明确地命名一个特定的函数模板。应该提供一个吗?或者,我们是否认为重载集应该作为一个整体传递给函数模板模板参数?如果重载决议然后选择 non-template 重载怎么办?在没有令人信服的用例的情况下,我们如何回答这些设计问题?

如果您相信自己知道如何解决所有这些问题,尤其是可以提供令人信服的论据来说明为什么我们需要语言中的此功能,尽管它会很复杂并且我们可以解决它的缺失使用 class template 模板参数,随时为标准编写提案。