类中声明std::queue模板成员报错:test::tasks非有效类成员模板
问题原因
你代码里的 template<typename T> std::queue<task<T>> tasks; 是非法的C++语法——类的非静态成员不能单独作为模板存在。非静态成员属于类的实例,必须是具体的类型,不能带有未实例化的模板参数。
解决方案
根据你的实际需求,有几种可行的修正方式:
方式1:将整个类改为模板类
如果你的test类本身就是为特定类型T设计的,直接把test声明为模板类,让T成为类的模板参数:
#include <functional> #include <vector> #include <queue> template<typename T> class test{ public: test()=default; private: struct task{ std::function<std::vector<T>(std::vector<T>)> func; }; std::queue<task> tasks; };
这样task结构体和tasks队列都依赖类的模板参数T,语法完全合法,每个test<T>实例都会有对应类型的队列。
方式2:用类型擦除存储多类型队列
如果需要同一个test实例能存储不同T类型的任务队列,可以用C++17引入的std::variant来封装所有需要支持的队列类型:
#include <functional> #include <vector> #include <queue> #include <variant> class test{ public: test()=default; // 示例:添加int类型的任务 void add_int_task(std::function<std::vector<int>(std::vector<int>)> f) { task<int> t{std::move(f)}; std::get<std::queue<task<int>>>(tasks).push(std::move(t)); } // 可按需添加其他类型的任务添加方法,比如add_double_task private: template<typename T> struct task{ std::function<std::vector<T>(std::vector<T>)> func; }; // 提前列出所有需要支持的T对应的队列类型 std::variant<std::queue<task<int>>, std::queue<task<double>>> tasks; };
这种方式需要提前确定要支持的类型,适合类型数量有限的场景。
方式3:声明为静态成员模板
如果tasks是所有test实例共享的全局队列,可以将其声明为静态成员模板:
#include <functional> #include <vector> #include <queue> class test{ public: test()=default; private: template<typename T> struct task{ std::function<std::vector<T>(std::vector<T>)> func; }; template<typename T> static std::queue<task<T>> tasks; }; // 静态成员模板必须在类外部定义 template<typename T> std::queue<typename test::task<T>> test::tasks;
注意:静态成员属于类本身,所有test实例会共享同一个T对应的队列,适合全局共享任务队列的场景。
内容的提问来源于stack exchange,提问作者Aerin
相关产品推荐
相关产品推荐

