【问题标题】:passing function template prototype as argument将函数模板原型作为参数传递
【发布时间】:2021-02-28 12:00:33
【问题描述】:

我正在尝试将模板化函数传递给另一个函数,如下所示:

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);
}

gcc10.2 中,我能够以同样的方式传递fun(模板原型) 作为指定类型fun&lt;&gt;.
请注意,如果我没有默认模板参数 T=bool,这将不起作用。

Clang11 这不起作用。
https://godbolt.org/z/9WfMdc

这是怎么回事?

【问题讨论】:

  • 我会说 gcc 错误。

标签: c++ templates gcc compiler-errors clang


【解决方案1】:

以下所有标准参考均参考N4659: March 2017 post-Kona working draft/C++17 DIS


这可以说是 GCC 错误(/extension 功能),虽然我还没有找到它的票。

根据[temp.names]/1,您可以通过template-id 引用模板专业化。后者的语法不允许省略尖括号&lt;&gt;,即使其中的template-argument-list 可能为空(opt):

模板特化可以由 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 >

在您的情况下,您希望引用函数模板 fun 的特化 fun&lt;bool&gt;,这与您可以通过使用默认模板参数引用的相同特化fun的单一类型模板参数,即fun&lt;&gt;。但是,您不能仅通过指定 fun 来引用 fun&lt;bool&gt; 专业化;后者不涉及专业化,因此,您的程序格式不正确。

【讨论】:

    【解决方案2】:

    您需要在传递fun 时指定T 是什么,因为您需要该参数的实例化来构建该函数。编译器需要以某种方式推断T

    编译器假定T 属于bool 类与funfun&lt;&gt;,但您不能摆脱默认模板参数,否则将无法推导出它。

    【讨论】:

    • 是的,很清楚为什么没有默认设置它就无法工作。我的问题是我是否可以在这种情况下互换使用funfun&lt;&gt;,因为它们是完全不同的东西。
    • 没错,它们是不同的,这就是为什么不编译是有道理的:) 不应允许忽略函数的模板定义并将其用作非模板函数。
    猜你喜欢
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 2012-06-07
    • 2014-08-02
    相关资源
    最近更新 更多