如何构造含不同模板参数的类的元组?C++模板编程问题
解决方案
你可以通过成员初始化列表结合std::make_tuple和完美转发来实现需求,避免在构造函数体内赋值,同时保留参数的左右值特性:
#include <tuple> #include <utility> // 用于std::forward和std::decay_t template<class T> struct A { A(T d) : m_t(d) {} private: double m_t; }; template<class... Ts> struct B { std::tuple<A<Ts>...> m_tuple; // 完美转发参数,直接在初始化列表中构造tuple template<class... Args> B(Args&&... args) : m_tuple(std::make_tuple(A<std::decay_t<Args>>(std::forward<Args>(args))...)) {} };
关键说明:
std::make_tuple会根据传入的A<std::decay_t<Args>>实例自动推导tuple类型,与m_tuple的std::tuple<A<Ts>...>类型匹配(前提是Args...去掉引用、const/volatile限定后与Ts...一一对应)。std::forward<Args>(args)用于完美转发构造参数,保留原始参数的左值/右值属性,避免不必要的拷贝。std::decay_t<Args>用于去除参数类型的引用、const/volatile限定符,确保A的模板参数为值类型(比如传入const int&时会转换成int)。
额外优化:编译期类型约束(C++20及以上)
如果需要确保构造函数的参数类型与B的模板参数Ts...严格匹配,可添加编译期约束,避免隐式转换带来的意外:
#include <concepts> #include <tuple> #include <utility> template<class T> struct A { A(T d) : m_t(d) {} private: double m_t; }; template<class... Ts> struct B { std::tuple<A<Ts>...> m_tuple; template<class... Args> requires (std::same_as<std::decay_t<Args>, Ts> && ...) B(Args&&... args) : m_tuple(std::make_tuple(A<Ts>(std::forward<Args>(args))...)) {} };
内容的提问来源于stack exchange,提问作者SpeakX
相关产品推荐
相关产品推荐

