繁体   English   中英

将函数作为参数传递给模板类的模板方法

[英]passing function as parameter to template method of template class

以下代码看起来合法但不编译

void f() {}

template<bool>
struct call_any
{
    template<typename F>
    static void call(F f) {}
};

template<bool B>
void call_f()
{
    call_any<true>::call<void (&)()>(f);  // OK
    call_any<false>::call<void (&)()>(f); // OK
    call_any<B>::call<void()>(f);         // OK
    call_any<B>::call<void (&)()>(f); // expected primary-expression before '>'
}

为什么会出现错误,这是什么意思?

当您处理依赖于模板中的模板参数的类型时,编译器不知道该类型的成员是什么类型的事物。 除非您另行指定,否则它假定成员不是类型而不是模板。 因此,它试图将<视为一个小于运算符,但是当它到达>时,就不可能解析表达式。

要摆脱错误,你应该使用它:

call_any<B>::template call<void (&)()>(f);

这告诉编译器显式call是一个模板,因此它应该将<视为模板参数的开头而不是常规的小于运算符。

这也应该使用template

call_any<B>::call<void()>(f); 

您没有在此行上看​​到错误的唯一原因是有一种方法可以将其解析为非模板:

(call_any<B>::call < void() ) > (f);

虽然很奇怪,但它在语法上是有效的,所以编译器会越过那一行,你看到的第一个错误是你提到的错误。 但是,如果没有template关键字,一旦call_f实际被实例化,你最终会得到一个错误(可能 - 它有奇怪的方式可以工作)。

前两个示例没有使用template关键字是可以的。 由于类型不依赖于模板参数,因此可以在解析call_f确定call是模板。

您可能会问:“为什么编译器无法确定它是模板?我已将其定义为上面代码中的模板!”。 问题是专业化。 您可以专门化模板并执行与主模板指定的完全不同的操作:

template<>
struct call_any<false>
{
    static const int call = 5;
};

即使在定义了call_f之后,这种特殊化也可能发生,因此编译器在解析call_f时不能依赖call_any的主要模板。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM