如何从StrongType元组生成PoD元组?
实现从StrongType元组提取POD元组的方案
你已经有了用于强类型封装的StrongType<>模板,现在需要从保存这类强类型实例的元组中提取底层POD值组成普通元组对吧?这里给你一套基于C++17及以上特性的简洁实现方案:
首先先确认你的StrongType定义(方便后续参考):
template <typename T, typename TAG> class StrongType { private: std::string mName; T mValue; public: explicit StrongType(std::string n) : mName(n), mValue() {} explicit StrongType(std::string n, T v) : mName(n), mValue(std::move(v)) { } const T &value() const { return mValue; } std::string name() const { return mName; } };
1. 保存StrongType元组的类实现
假设你的元组持有类结构如下(如果你的类已有其他逻辑,只需替换核心的提取方法即可):
#include <tuple> #include <string> template <typename... StrongTypes> class StrongTupleHolder { private: std::tuple<StrongTypes...> m_strongTuple; public: // 构造函数:直接接收StrongType实例初始化元组 explicit StrongTupleHolder(StrongTypes&&... args) : m_strongTuple(std::forward<StrongTypes>(args)...) {} // 核心方法:返回底层POD组成的普通元组 auto getPlainTuple() const { // 用std::apply遍历元组每个元素,提取底层POD值 return std::apply([](const auto&... strongItems) { // 折叠表达式逐个调用value(),组装成普通元组 return std::make_tuple(strongItems.value()...); }, m_strongTuple); } };
2. 核心逻辑解释
std::apply是C++17的标准工具,它能把元组的每个元素展开为lambda的参数,完美适配元组遍历需求。- lambda中的
strongItems.value()...是折叠表达式,会对元组里的每个StrongType实例调用value()方法,获取底层POD值。 - 最终
std::make_tuple会自动推导类型,生成对应POD类型组成的普通元组。
3. 使用示例
为了区分不同强类型,我们需要定义专属的TAG类型(这是StrongType的核心设计之一),测试流程如下:
#include <iostream> // 定义TAG类型,用于区分不同强类型 struct UserIdTag {}; struct UserAgeTag {}; struct UserScoreTag {}; // 定义具体强类型别名 using UserId = StrongType<unsigned int, UserIdTag>; using UserAge = StrongType<int, UserAgeTag>; using UserScore = StrongType<float, UserScoreTag>; int main() { // 创建持有强类型元组的实例 StrongTupleHolder<UserId, UserAge, UserScore> holder( UserId("User ID", 1001), UserAge("User Age", 28), UserScore("User Score", 92.5f) ); // 获取普通POD元组 auto plainTuple = holder.getPlainTuple(); // 验证结果:plainTuple类型为std::tuple<unsigned int, int, float> std::cout << "User ID: " << std::get<0>(plainTuple) << "\n"; std::cout << "User Age: " << std::get<1>(plainTuple) << "\n"; std::cout << "User Score: " << std::get<2>(plainTuple) << "\n"; return 0; }
4. 通用提取函数(可选)
如果不需要封装在类里,也可以写一个独立的通用函数直接转换任意StrongType元组:
template <typename... StrongTypes> auto extractPlainTuple(const std::tuple<StrongTypes...>& strongTuple) { return std::apply([](const auto&... items) { return std::make_tuple(items.value()...); }, strongTuple); } // 使用方式: // std::tuple<UserId, UserAge> strongTuple{UserId("ID", 1001), UserAge("Age",28)}; // auto plainTuple = extractPlainTuple(strongTuple);
这个方案完全基于C++标准库,类型安全,能保证提取的POD类型和原StrongType的底层类型严格对应。
内容的提问来源于stack exchange,提问作者HappyCactus
相关产品推荐
相关产品推荐

