C++非模板类中如何持有匹配指定Layout的Reader模板类成员?
解决方法
一、修复AReaderHolder的成员类型问题
C++不允许在非静态类成员声明阶段进行模板参数推导,必须明确Reader的具体类型。可以通过**类型萃取(Type Traits)**从ALayout中提取对应的参数包,进而得到匹配的Reader类型:
1. 定义Layout类型萃取模板
#include <tuple> // 基础模板,用于匹配Layout类型 template<typename T> struct LayoutTraits; // 特化版本,提取Layout的参数包 template<typename... Args> struct LayoutTraits<Layout<Args...>> { using ReaderType = Reader<Args...>; // 直接得到匹配的Reader类型 using ArgsTuple = std::tuple<Args...>; // 可选:保存参数包为tuple类型 };
2. 修改AReaderHolder实现
class AReaderHolder { public: AReaderHolder() : _reader{ALayout{}} {} private: // 使用萃取得到的具体Reader类型 typename LayoutTraits<ALayout>::ReaderType _reader; };
二、让ALayout与AReader共享参数包,避免重复编写
如果想从根源上避免重复书写参数包<int, double>,可以通过中间类型封装参数包,再从中间类型推导Layout和Reader:
方法1:以Layout为桥梁(推荐)
直接利用上面的LayoutTraits,从已定义的ALayout推导AReader:
using ALayout = Layout<int, double>; using AReader = typename LayoutTraits<ALayout>::ReaderType;
方法2:用Tuple封装参数包
先将参数包存入std::tuple,再通过萃取模板推导对应的Layout和Reader:
#include <tuple> // 基础模板,用于匹配tuple类型 template<typename Tuple> struct TupleToTypes; // 特化版本,从tuple提取参数包 template<typename... Args> struct TupleToTypes<std::tuple<Args...>> { using LayoutType = Layout<Args...>; using ReaderType = Reader<Args...>; }; // 定义参数包的tuple别名 using AArgs = std::tuple<int, double>; // 从tuple推导Layout和Reader using ALayout = typename TupleToTypes<AArgs>::LayoutType; using AReader = typename TupleToTypes<AArgs>::ReaderType;
方法3:C++20及以上:用别名模板简化
如果使用C++20,可以直接用别名模板封装参数包的复用逻辑:
template<typename... Args> struct TypeBundle { using LayoutType = Layout<Args...>; using ReaderType = Reader<Args...>; }; // 定义参数包对应的Bundle using ABundle = TypeBundle<int, double>; // 直接提取所需类型 using ALayout = ABundle::LayoutType; using AReader = ABundle::ReaderType;
内容的提问来源于stack exchange,提问作者flyfisher
相关产品推荐
相关产品推荐

