【问题标题】:Is it possible to pass a function template as a template argument?是否可以将函数模板作为模板参数传递?
【发布时间】:2012-02-24 17:18:15
【问题描述】:

假设我们有一个模板函数:

template<typename T1, typename T2, typename T3>
T3 such_fun(T1 a, T2 b) {
    // do something...
}

现在我们想将它用作另一个模板中的参数,例如像这样

template<typename T1, template<typename, typename, typename> some_function>
void big_fun(T1 a) {
   // some code...
   a = some_function<T1, T1, T1>(a, a);
   // some code...
}

有可能吗?

我知道我可以使用带有已定义 () 运算符的结构。我只是对函数很好奇。

编辑:

在我写这个问题时,我的朋友找到了部分解决方案:

template<typename T1, T1 (*some_function)(T1, T1)>
void big_fun(T1 a) {
   // some code...
   a = some_function(a, a);
   // some code...
}

但仍然 - 我很好奇是否有可能在调用之前不实现函数类型。例如 - 我可能想用各种类型组合调用传递的模板:

template<typename T1, typename T2, template<typename, typename, typename> some_function>
void big_fun(T1 a, T2 b) {
   // some code...
   a = some_function<T1, T1, T1>(a, a);
   a = some_function<T1, T2, T1>(a, b);
   b = some_function<T2, T2, T2>(b, b);
   b = some_function<T2, T1, T2>(b, a);
   // some code...
}

【问题讨论】:

    标签: c++ templates template-meta-programming


    【解决方案1】:

    不,这是不可能的。从 N3337 中的 14.3.3 开始:

    模板模板参数的模板参数应为 类模板或别名模板的名称,表示为 id 表达式。当模板参数命名一个类模板时, 匹配模板时只考虑主类模板 带有相应参数的模板参数;部分的 即使参数列表匹配,也不考虑特化 模板模板参数的那个。

    第一段只明确提到了类模板。我想这也不值得麻烦,因为您已经可以使用函数或 std::function 作为参数来做一些非常相似的事情。

    【讨论】:

    • 我一个字都听不懂你在说什么。-1,你能不能给我们不流利的普通话提供一个例子?
    • @lurscher 因为不明白这是一个可怕的拒绝投票的理由。当他们谈论量子物理学时,我不会对量子物理学家投反对票,因为我不懂。
    • @SethCarnegie,我不同意。我认为这本身就是一个很好的理由。此外,答案也是错误的;这个问题想要做的事情是完全可能的,即使在 c++03 中也是如此。我认为 SO 的要求与 pmr 的回答之间存在脱节,因此投反对票。如果他改进了他的答案,我会非常乐意撤回它
    • @lurscher 你说问题想要做什么是完全不可能的,这个答案的第一句话是“不,这不可能。”什么是断开连接?
    • @lursher,我很高兴阅读您的 c++03 解决方案。 pmr 写的对我来说意味着只有类模板或其别名可以是模板模板参数(即模板本身就是模板的参数)。
    【解决方案2】:

    C++ 中的模板在编译时使用具体类型进行编译。他们必须知道。

    这表示您可以通过传递可以推导出参数的函数模板来进一步使用您的部分解决方案。请注意,这与使用具体类型显式传递函数没有什么不同,您只需键入更少。

    template<typename T>
    T square(T a, T b)
    {
        return a * b;
    }
    
    template<typename T, T (*some_function)(T, T)>
    T test(T a) 
    {
       return square (a, a);
    }
    
    void main()
    {
        int a = test<int, square>(2);
        float b = test<float, square>(2.2f);
    }
    

    【讨论】:

    • 我看不出该代码与“部分解决方案”代码之间的区别。问题是,在这种方法中,如果不明确添加新的模板参数,就不可能将some_function 与各种类型一起使用。我很好奇是否有更灵活(但仍然没有类使用)的方式。
    【解决方案3】:

    只要template&lt; typename T1, typename T2, typename T3&gt; someTemplate 评估为某个实际类而没有错误,您就可以在其他模板内外任意组合使用它。

    你试过编译它吗?告诉我们你得到了什么错误(和具体示例)

    【讨论】:

    • 我知道我可以使用一个类。我在我的帖子里写过。问题是关于常用功能。但根据@pmr 所写的 - 这在语法上似乎是不可能的。
    • OP(以及您的扩展)使用的语法无效。正确的是template&lt;typename T1&gt; class someTemplate。这里也没有关于evaluation 的内容。想象一下:模板模板参数只能与具有相同模板参数列表的类模板的名称匹配(这对于非类型模板参数很重要)。然后将该模板名称注入到另一个模板中,并可以在那里进行实例化。问题是class template。我没有看到这种限制的具体原因,但我不是委员会成员,也不是语言律师。
    • @pmr 嗯。好吧。我在示例中使用的语法部分是伪代码,即我知道我不能使用 class 关键字,所以我没有使用任何关键字。这是关于想法的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 2019-11-30
    • 1970-01-01
    • 2022-01-16
    相关资源
    最近更新 更多