在编译时动态生成结构

emi*_*rax 2 c++ templates structure template-meta-programming c++11

我必须生成一个仅在某些条件下包含某些字段的数据结构.这通常总是转化为以下内容

struct MyStruct {
    int     alwaysHere;

#ifdef WHATEVER
    bool    mightBeHere;
#endif

    char    somethingElse;

#if SOME_CONSTANT > SOME_VALUE
    uint8_t alywasHereButDifferentSize;
#else
    uint16_t alywasHereButDifferentSize;
#endif
...
};
Run Code Online (Sandbox Code Playgroud)

从我的观点来看,这看起来很难看,而且难以理解.甚至没有谈论处理这些字段的代码,通常也在ifdef下.

我正在寻找一种优雅的方法来实现相同的结果,而不会增加任何开销,但代码更具可读性.模板专业化似乎有点过分,但在我看来它是唯一的选择.

C++ 11是否会添加任何内容来处理这种情况?

任何建议将不胜感激.

Jer*_*fin 5

对于第二种情况,我通常更喜欢将hackery限制在一个地方的typedef:

#if SOME_CONSTANT > SOME_VALUE
    typedef uint8_t always_type;
#else
    typedef uint16_t always_type;
#endif
Run Code Online (Sandbox Code Playgroud)

然后你的其余代码将在always_type整个过程中使用:

struct MyStruct {
    // ...
    always_type always_here_but_different_size;
    // ...
};
Run Code Online (Sandbox Code Playgroud)

如果你想使用:

typedef std::conditional<(SOME_CONSTANT > VALUE), uint8_t, uint16_t>::type always_type;
Run Code Online (Sandbox Code Playgroud)

这很好 - 这里的重点不是你用来获得你想要的类型的语法,而是你通常想为这个类型创建一个名字,这样你就可以在需要的地方使用它.

至于存在与否的情况,这有点难以说.通常,这样的事情将涉及在构建时启用/禁用某些功能.如果是这样,那么该类似乎具有与可以启用/禁用的功能相关的职责,以及与其他功能相关的职责.这听起来似乎违反了单一责任原则,可能不是很有凝聚力.如果是这种情况,它可能表明在整体设计层面上更好地解决的问题,而不仅仅是您使用的语法.

警告:我可能从公认的最小证据中推断出相当多的一些 - 可能超过证据确实支持的证据.