C++11下如何用对应参数包构造Alphabet类的可变参数std::tuple
在C++11中实现Alphabet类的参数对应构造
完全可行。C++11虽然没有标准库提供的std::integer_sequence,但可以手动实现类似的索引序列工具,配合可变参数模板和完美转发,就能实现每个参数对应构造TLetters中对应位置类的需求。
核心思路
通过索引序列将参数包中的每个元素,精准转发给std::tuple中对应位置的Letter类构造函数,避免把所有参数传递给每个Letter类。
实现步骤及代码示例
1. 先定义基础的Letter类(模拟用户的A、B、C类)
#include <tuple> #include <utility> // 用于std::forward // 模拟用户的Letter类及对应参数类型 struct ArgA {}; struct A { A(ArgA) {} }; struct ArgB {}; struct B { B(ArgB) {} }; struct ArgC {}; struct C { C(ArgC) {} };
2. 手动实现C++11版的索引序列工具
因为C14才将std::integer_sequence纳入标准,C11需要自己实现:
// 基础索引序列模板 template <typename T, T... Ints> struct IntegerSequence { using value_type = T; static constexpr std::size_t size() noexcept { return sizeof...(Ints); } }; // 用于生成索引序列的辅助模板 template <typename T, T N, T... Ints> struct MakeIntegerSequenceHelper : MakeIntegerSequenceHelper<T, N-1, N-1, Ints...> {}; template <typename T, T... Ints> struct MakeIntegerSequenceHelper<T, 0, Ints...> { using type = IntegerSequence<T, Ints...>; }; // 对外接口:生成从0到N-1的索引序列 template <std::size_t N> using MakeIndexSequence = typename MakeIntegerSequenceHelper<std::size_t, N>::type;
3. 实现Alphabet类的正确构造逻辑
template <typename... TLetters> class Alphabet { private: std::tuple<TLetters...> letters; // 私有构造函数:接收索引序列和参数包,精准转发每个参数 template <std::size_t... Indices, typename... Args> Alphabet(MakeIndexSequence<sizeof...(TLetters)>, Args&&... args) : letters(std::forward<TLetters>(TLetters(std::get<Indices>(std::forward_as_tuple(std::forward<Args>(args)...))))...) {} public: // 公共构造函数:生成索引序列并转发给私有构造 template <typename... Args> Alphabet(Args&&... args) : Alphabet(MakeIndexSequence<sizeof...(TLetters)>(), std::forward<Args>(args)...) {} };
4. 测试代码
int main() { // 正常编译:每个参数对应构造一个Letter类 Alphabet<A, B> alphabet2(ArgA(), ArgB()); Alphabet<A, B, C> alphabet3(ArgA(), ArgB(), ArgC()); return 0; }
原理说明
MakeIndexSequence<N>会生成包含0,1,...,N-1的索引序列,其中N是TLetters的数量。- 在私有构造函数中,利用
std::get<Indices>从参数包的元组中取出对应位置的参数,传递给对应位置的TLetters类构造函数,再把这些构造好的对象传入std::tuple。 - 通过
std::forward实现完美转发,保证参数的类型和值类别(左值/右值)正确传递。
内容的提问来源于stack exchange,提问作者pic32cpp
相关产品推荐
相关产品推荐

