C++14编译报错:类模板TaskEvent提示expected type-specifier而函数模板正常
错误原因
你当前使用C++14标准编译代码,该版本仅支持函数模板的参数自动推导,不支持类模板的参数自动推导:
DispatchToMethod是函数模板,编译器可以根据传入的实参自动推导模板参数类型,因此可以正常调用。TaskEvent是类模板,C++14标准无法通过构造函数的实参自动推导类的模板参数,编译器无法识别你写的TaskEvent(...)写法,因此抛出类型说明符缺失的报错。
解决方法
你可以根据自己的需求选择以下任意一种方案解决:
方案1:手动指定类模板参数
不需要修改编译标准,只需在实例化TaskEvent时手动补充模板参数即可,代码修改如下:
// 利用decltype自动获取类型,不需要手动手写复杂的成员函数指针、tuple类型 auto e = new TaskEvent<Foo, decltype(&Foo::Add), decltype(std::make_tuple(1, 2))>(&foo, &Foo::Add, std::make_tuple(1, 2));
方案2:新增函数模板类型推导的工厂函数
如果需要频繁实例化TaskEvent,可以新增一个工厂函数复用推导逻辑:
首先在TaskEvent类定义的外部新增如下工厂函数:
#include <type_traits> // 用到decay_t需要加这个头 template <typename Obj, typename Method, typename Args> TaskEvent<Obj, Method, std::decay_t<Args>> MakeTaskEvent(Obj* obj, Method method, Args&& args) { return TaskEvent<Obj, Method, std::decay_t<Args>>(obj, method, std::forward<Args>(args)); }
随后将报错行替换为工厂函数调用即可:
auto e = MakeTaskEvent(&foo, &Foo::Add, std::make_tuple(1,2));
工厂函数是函数模板,C++14下支持自动推导参数类型,无需手动指定模板参数。
方案3:升级编译标准到C++17及以上
C++17开始正式支持类模板参数推导(CTAD),你只需要将编译命令中的-std=c++14修改为-std=c++17,原有代码不需要做任何修改即可正常编译运行。
内容的提问来源于stack exchange,提问作者Wu Jo
相关产品推荐
相关产品推荐

