C++;11带有类成员和constexpr链接时间优化的枚举

C++;11带有类成员和constexpr链接时间优化的枚举,constexpr,enum-class,lto,Constexpr,Enum Class,Lto,在我的项目中,我有很多枚举,它们需要与枚举成员关联的附加属性和与枚举类型关联的辅助静态方法 据我所知,标准枚举类MyItem{…}不可能实现这一点,因此对于我的项目中的每个枚举类,我都有一个辅助类MyItemEnum,它封装了这些辅助静态方法,还实例化了自身的辅助实例,这样我就可以访问它们的方法以获得附加属性 下面是一个例子(尽可能简化,但我相信所有要讨论的特性都停留在这里) MyItem.h enum class MyItem : unsigned int { Item1 = 1,

在我的项目中,我有很多枚举,它们需要与枚举成员关联的附加属性和与枚举类型关联的辅助静态方法

据我所知,标准枚举类MyItem{…}不可能实现这一点,因此对于我的项目中的每个枚举类,我都有一个辅助类MyItemEnum,它封装了这些辅助静态方法,还实例化了自身的辅助实例,这样我就可以访问它们的方法以获得附加属性

下面是一个例子(尽可能简化,但我相信所有要讨论的特性都停留在这里)

MyItem.h

enum class MyItem : unsigned int {
    Item1   = 1,
    Item2   = 5
};

class MyItemEnum {
private:
    MyItem myItem;
    size_t extInfo;

    MyItemEnum(const MyItem& myItem, size_t extInfo);
    ~MyItemEnum();
public:
    static MyItemEnum Item1;
    static MyItemEnum Item2;
    static const MyItemEnum &get(MyItem myItem);

    operator MyItem() const;
    size_t getExt() const;
    bool hasNext() const;
    MyItem next() const;
};
我认为其含义是显而易见的,我不需要在这里提供.cpp部分。。。当我需要访问扩展功能时,我使用MyItem作为要在接口和MyItemEnum中传递的参数

<强>我的第一个问题是,上面的方法是OK,还是我应该考虑完全不同的东西?<强> < /P> 我的第二个问题涉及我正试图使用constexpr对此枚举进行的优化:

enum class MyItem : unsigned int {
    Item1   = 1,
    Item2   = 5
};

class MyItemEnum {
private:
    MyItem myItem;
    size_t extInfo;

    constexpr MyItemEnum(const MyItem& myItem, size_t extInfo);
public:
    static MyItemEnum Item1;
    static MyItemEnum Item2;
    static constexpr MyItemEnum &get(MyItem myItem);

    constexpr operator MyItem();
    constexpr size_t getExt();
    constexpr bool hasNext();
    constexpr MyItem next();
};
它可以编译,但显然constexpr没有被使用的机会,因为如果我访问:

MyItemEnum::Item1.getExt()
因此编译器不知道Item1实例化时使用了哪些值。 在链路时间优化过程中,是否有可能将上述表达式计算为constexpr? 或者我可以使用

static constexpr MyItemEnum Item1 = MyItemEnum(MyItem::Item1, 123);

这将激活constexpr编译时优化,但我担心在某些情况下,当无法对constexpr进行编译时计算时,编译器必须创建MyItemEnum的本地实例(而不是使用对单个全局静态实例的引用)我担心这会导致性能下降(我的实际枚举的属性比单个成员多,因此本地实例化可能需要一些时间?)这是一个合理的担忧吗?

我还没有使用
constexpr
和由此产生的编译器优化的直接经验,但我可以告诉您,只要在类本身或实例的成员上使用
const
,VS2012和g++4.7编译器就可以进行跨模块优化:

class MyItemEnum {
private:
    // make sure to put const here...
    const MyItem myItem;
    const size_t extInfo;

    MyItemEnum(const MyItem& myItem, size_t extInfo);
    ~MyItemEnum();
public:
    // and put const in here too...
    static const MyItemEnum Item1;
    static const MyItemEnum Item2;
};
<> >注意,构造函数必须使用C++样式初始化列表语法,如果只是用常量值填充它们,这不应该是问题。(初始值设定项列表仅在需要进行非常重要的设置时才会成为一个难题)


我还没有在Clang/LLVM上验证过这一点,所以如果这是您的工具链,那么我强烈建议您使用这个简化的示例,并自行消除结果。即使您不熟悉汇编语言,简单测试用例的反汇编也很容易解析。在这种情况下,您可以编译两个版本:一个在单个模块中,一个分为两个模块,并比较结果以确保LTO正在完成您需要的工作。

我认为您应该将其分解为单独的问题。