C++20实现tuple时可变参数包扩展初始化base类构造的正确方法
C++20 tuple实现构造函数补全方案
你需要将/* !! HERE SHALL THE MAGIC COME */位置替换为如下代码:
wrap<INDEX, Ts>(args)...
实现原理
- 此处
INDEX、Ts、args三个参数包长度完全一致,按照C++可变参数包的展开规则,三个包会按位置一一配对展开 - 每一组对应位置的参数会展开为
wrap<第N位索引, 第N位类型>(第N位参数)的形式,刚好匹配每个wrap基类的构造函数签名,完成对应基类的初始化
修正后完整代码
#include <utility> // 包含index_sequence相关实现 template<size_t INDEX, typename T> struct wrap { [[no_unique_address]] T data {}; }; template<typename...> class base {}; template<size_t... INDEX, typename... Ts> class base<std::index_sequence<INDEX...>, Ts...> : public wrap<INDEX, Ts>... { public: constexpr base( const Ts &... args ) : wrap<INDEX, Ts>(args)... {} }; template<typename... Ts> class tuple : public base<std::index_sequence_for<Ts...>, Ts...> { public: /* Inherit base constructors */ using base<std::index_sequence_for<Ts...>, Ts...>::base; };
可选优化方案
如果需要支持移动语义提升性能,可以将构造函数改为通用引用版本:
template<typename... Args> requires (std::is_constructible_v<Ts, Args> && ...) constexpr base( Args&&... args ) : wrap<INDEX, Ts>(std::forward<Args>(args))... {}
内容的提问来源于stack exchange,提问作者Martin Kopecký
相关产品推荐
相关产品推荐

