将函数作为参数传递给模板类的模板方法
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
是正在解析call_f
的模板。
你可能会问:"为什么编译器不能弄清楚它是一个模板?我在上面的代码中已经把它定义为模板了!"。问题在于专业化。您可以专门化模板,并执行与主模板指定的完全不同的操作:
template<>
struct call_any<false>
{
static const int call = 5;
};
即使在定义了call_f
之后,这种专门化也可能发生,因此编译器在解析call_f
时不能依赖于call_any
的主模板所说的内容。
相关文章:
- 将成员函数指针作为参数传递给模板方法
- C++11:模板方法的模板函数调用无法编译?
- 定义类模板构造函数的两种方法之间的区别
- 将函数和成员函数传递给模板方法
- 将对象传递给模板构造函数或方法的正确方法是什么
- 模板方法定义的问题 - 错误C2244:无法将函数定义与现有声明匹配
- 调用模板布尔函数的最佳方法
- 基于方法或自由函数存在的模板构造函数解析
- 如何将模板方法模式应用于具有不同签名的函数
- 将非模板函数指针传递到模板方法中
- 在另一个类的模板成员函数中调用模板类中的方法
- 从数据类型调用构造函数(或任何函数/方法)而不经历两个模板化函数的任何类型的方法
- 如何专门化模板化类,以采用不带参数的方法函数类型
- 私有基类通过子类中的模板友元函数和模板方法影响成员访问
- 从模板函数调用静态模板方法
- 将函数作为参数传递给模板类的模板方法
- 是否有一种方法可以使用SFINAE来确定对模板化函数的调用是否会由于所提供的类型而失败
- 根据构造函数的可访问性在函数之间进行选择的模板方法
- 在c++中有使用模板化函数的方法吗?
- 如何使用type_traits或模板函数专门化来整合模板方法