基于枚举值类型的结构

问题描述 投票:0回答:1

所以我有一个结构体,比如

A
和一个枚举,比如
AE
。我想根据枚举值获取结构成员的类型。我想出了下面的解决方案,这似乎有效。

#include <iostream>
#include <type_traits>

struct A
{
    int a;
    double b;
};

enum AE
{
    TYPE1,
    TYPE2
};

template<AE> struct TypeMap;

template<>
struct TypeMap<AE::TYPE1>
{
    using type = decltype(A::a);
};

template<>
struct TypeMap<AE::TYPE2>
{
    using type = decltype(A::b);
};


int main()
{
    TypeMap<AE::TYPE1>::type a;
    TypeMap<AE::TYPE2>::type b;
    std::cout << typeid(a).name() << '\n';
    std::cout << typeid(b).name() << '\n';
}

但是,我必须专门针对每个枚举值和结构成员。有没有更优雅的方法来做到这一点?就像以某种方式使用

TypeMap
或函数设置
type
一样?
用例是使用它从 AttributeRetriever 获取基于枚举类型的属性:

if constexpr

上面是涉及继承的类工厂解决方案的替代解决方案,例如:

#include <type_traits> #include <string> #include <memory> #include <iostream> enum class ErrorCode { OK, FAILURE }; template <typename ValueType> class Result { // some members and functions }; struct Attributes { uint16_t attribute1; uint8_t attribute2; bool attribute3; //friend std::ostream& operator<<(std::ostream& os, const Attributes& info); }; enum AttributeType { TYPE1, TYPE2, TYPE3 }; template<AttributeType> struct TypeMap; template<> struct TypeMap<AttributeType::TYPE1> { using type = decltype(Attributes::attribute1); }; template<> struct TypeMap<AttributeType::TYPE2> { using type = decltype(Attributes::attribute2); }; template<> struct TypeMap<AttributeType::TYPE3> { using type = decltype(Attributes::attribute3); }; class AttributeRetriever { public: template<AttributeType AT> Result<typename TypeMap<AT>::type> get() { using R = Result<typename TypeMap<AT>::type>; if constexpr(AT == AttributeType::TYPE1) { return R(60); } else if (AT == AttributeType::TYPE2) { return R(3); } else if (AT == AttributeType::TYPE3) { return R(false); } } }; int main() { AttributeRetriever ar; std::cout << ar.get<AttributeType::TYPE1>().value() << '\n'; std::cout << static_cast<uint32_t>(ar.get<AttributeType::TYPE2>().value()) << '\n'; std::cout << ar.get<AttributeType::TYPE3>().value() << '\n'; }


c++ templates struct enums
1个回答
0
投票

class AttributeRetriever { public: using Status = bool; virtual Status get(Attributes& attributes) = 0; }; class Attributetype1 : public AttributeRetriever { public: Status get(Attributes& attributes) override { attributes.attribute1 = 60; return true; } }; std::unique_ptr<AttributeRetriever> factory(AttributeType at) { if (at == TYPE1) return std::make_unique<Attributetype1>(); ... }

将相当于您的
struct Attributes { uint8_t attribute2; uint16_t attribute1; bool attribute3; }

。 现有的迂回解决方案如“

magic get
”,但通常有两种方法可以做类似的事情。 a) 指向成员的指针。您可以将它们用作模板参数:

Attributes

在这种情况下,您的枚举完全消失:它与字段名称合并,删除重复项。

b) 宏。您可以使用为每个类成员创建结构专业化的宏来声明字段:

template<auto m> struct field_getter; template<typename T, typename FieldType, FieldType T::*MemberPtr> struct field_getter<MemberPtr> { static FieldType get(const T* ptr){ return ptr->*MemberPtr; } };

(您可以通过更多的宏观工作来自动编号,但这超出了您的问题的范围。)

© www.soinside.com 2019 - 2024. All rights reserved.