【问题标题】:compile time indexer for enum classes枚举类的编译时索引器
【发布时间】:2020-09-27 04:35:20
【问题描述】:

如果给定一组枚举类,您将如何创建一种编译时索引器,它能够正确创建唯一标识符。

Template<class... Args>
struct Indexer
{

template<class T>
Indexer(T value)
  {
  value_ = someconstexprfunction<T>(value, interDistance_);
  }

int enumInternalIndexCode() { /* ... */ };
int effectiveEnumCode() { /* ... */  }

static constexpr int enumDistance_ = 100;
int value_ = 0;
};

// Usage:
enum class A {a,b,c,d,e}; enum class B{ a1,b1,c1}; enum class C{z,y,q};
using MyIndexer = Indexer<A,B,C>;
MyIndexer(A::a) t1; // value_ == 0
MyIndexer(B::a1) t2; //value_ ==  100
MyIndexer(B::b1) t3; //value_ ==  101
MyIndexer(C::z) t4; //value_ ==  200
t4.effectiveEnumCode(); // returns 0 (first element of the enum)
t4.enumInternalIndexCode(); // returns 2 (third enum in the Arg list (0,1,2) )

理想情况下,这应该能够工作,或者至少在编译时执行散列计算,更理想的是它应该在 C++11 中工作。这可行吗?谢谢!

【问题讨论】:

  • effectiveEnumCode 是不可能的,你能得到的只是枚举值本身。
  • 为什么不呢?我知道如果我使用额外的内存并在构建时保存它可以得到它,但理想的情况是在这个结构中只有 value_ ..也许使用带有枚举大小信息的外部特征?
  • 喜欢here ?
  • 仅当对象为constexpr

标签: c++ c++11 templates template-meta-programming constexpr


【解决方案1】:
#include <type_traits>
#include <cstddef>

template <typename T, typename... Ts>
struct Index;

template <typename T, typename... Ts>
struct Index<T, T, Ts...>
    : std::integral_constant<std::size_t, 0> {};

template <typename T, typename U, typename... Ts>
struct Index<T, U, Ts...>
    : std::integral_constant<std::size_t, 1 + Index<T, Ts...>::value> {};

template <typename... Args>
class Indexer
{
public:
    template <typename T>
    constexpr Indexer(T value)
        : _value(Index<T, Args...>::value * _enumDistance + static_cast<int>(value)) {}

    constexpr int enumInternalIndexCode() const { return _value / _enumDistance; }
    constexpr int effectiveEnumCode() const { return _value % _enumDistance; }
    constexpr int value() const { return _value; }

private:
    static constexpr int _enumDistance = 100;
    int _value = 0;
};

DEMO

但是请注意,这会将枚举器本身作为有效代码返回。

【讨论】:

  • 我能问你关于枚举器值本身的确切含义吗?
  • enum e { a, b = 2 },这里是b,你可能想要1,而代码返回2
  • 在我的情况下,我只需要 2,因为我想在将来转换回特定的枚举值
  • 那对你来说不是问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多