具有类成员和constexpr链接时优化的C ++ 11枚举 [英] C++11 enum with class members and constexpr link-time optimization

查看:292
本文介绍了具有类成员和constexpr链接时优化的C ++ 11枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,我有很多枚举,这些枚举需要具有与枚举成员关联的其他属性以及与枚举类型关联的辅助静态方法。

In my project I have a lot of enumerations that need to have additional attributes associated with the enumeration members and auxiliary static methods associated with the enumeration type.

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

As much as I know, this is not possible to have with the standard enum class MyItem {...}, so for each enum class in my project I have an auxiliary class MyItemEnum that encapsulates these auxiliary static methods and also instantiates auxiliary instances of itself, so that I can access their methods in order to get additional attributes.

下面是一个示例(尽可能简化,但我相信所有要讨论的功能都保留在那里) 。

Bellow an example (simplified as much as possible but I believe all the features to be discussed stayed there).

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中传递的参数。

I think the meaning is obvious and I don't need to provide here the .cpp part... I use the MyItem as an argument to be passed in the interfaces and MyItemEnum when I need to access the extended functionality.

我的第一个问题是

我的第二个问题涉及我试图使用constexpr进行的枚举优化:

My second question concerns an optimization of this enumeration that I am trying to do using 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显然没有机会被使用,因为如果我访问:

It compiles but apparently the constexpr doesn't get chance to get used because if I access:

MyItemEnum::Item1.getExt()

,因此编译器不知道Item1实例化了什么值。
在链接时间优化过程中是否有可能将上面的表达式评估为constexpr?
或者我可以使用

so the compiler doesn't know what values was Item1 instantiated with. Is there a chance that the expression above will be evaluated as constexpr during the link time optimization? Alternatively I could use

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

这将激活constexpr的编译时间优化,但是在某些情况下,恐怕 constexpr不可能在编译时评估,编译器必须创建MyItemEnum 的本地实例(而不是使用对单个全局静态实例的引用),我担心这可能会导致性能下降。惩罚(我的真实枚举不只是单个成员具有更多的属性,因此本地实例化可能需要一些时间吗?)。 这是有道理的问题吗?

This would active the constexpr compile time optimizations but I am afraid that in some cases, when the constexpr is not possible to be compile-time evaluated, the compiler would have to create a local instance of MyItemEnum (instead of using reference to a single global static instance) and I am afraid that this could lead to a performance penalty (my real enums has more attributes than just a single member so the local instantiation can take some time?). Is this a justified concern?

推荐答案

我没有使用<$的直接经验。 c $ c> constexpr 以及生成的编译器优化,但是我可以告诉您,只需在类本身的成员上使用 const 实例将同时使用VS2012和g ++ 4.7编译器进行跨模块优化:

I haven't direct experience with the use of constexpr and the resulting compiler optimizations yet, but I can tell you that simply using const on the members of the class itself or the instances will both VS2012 and g++ 4.7 compilers to do cross-module optimization:

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 ++样式初始化列表语法,如果您无论如何都只是用常量值填充它们的话,这应该不是问题。 (只有在需要进行非常规设置时,初始化列表才会变得很痛苦。)

The caveat is that the constructor must use the C++ style initializer list syntax, which shouldn't be a problem if you're just populating them with constant values anyway. (initializer lists only become a pain when non-trivial setup is required).

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

I have not verified this on Clang/LLVM, so if that's your toolchain then I strongly recommend you take this simplified example and disasm the result yourself. Disassembly of simple test cases can be pretty easy to parse even if you're not familiar with assembly languages. And in this case you can compile two builds: one set in a single module, and one split into two modules - and compare the results to make sure LTO is doing the job you need it to.

这篇关于具有类成员和constexpr链接时优化的C ++ 11枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆