C++ 在编译时动态生成结构
我必须生成一个只在特定条件下包含特定字段的数据结构。这通常会转化为以下内容C++ 在编译时动态生成结构,c++,templates,c++11,structure,template-meta-programming,C++,Templates,C++11,Structure,Template Meta Programming,我必须生成一个只在特定条件下包含特定字段的数据结构。这通常会转化为以下内容 struct MyStruct { int alwaysHere; #ifdef WHATEVER bool mightBeHere; #endif char somethingElse; #if SOME_CONSTANT > SOME_VALUE uint8_t alywasHereButDifferentSize; #else uint16_t
struct MyStruct {
int alwaysHere;
#ifdef WHATEVER
bool mightBeHere;
#endif
char somethingElse;
#if SOME_CONSTANT > SOME_VALUE
uint8_t alywasHereButDifferentSize;
#else
uint16_t alywasHereButDifferentSize;
#endif
...
};
在我看来,这很容易让人看得难看,看不懂。
甚至不讨论处理这些字段的代码,通常在
伊夫迪夫也是
我正在寻找一种优雅的方法来实现相同的结果,而不增加任何开销,但代码太复杂
更具可读性。模板专门化似乎有点过分,但在我看来
这是唯一的选择
C++11是否添加了任何东西来处理这种情况
如果您有任何建议,我们将不胜感激。我已经看到工会已经完成了这项工作(http://www.cplusplus.com/doc/tutorial/other_data_types/),但我不确定具体细节,因为我自己从未实施过。与第二个macrohackery不同,您将拥有:
union {
uint8_t alywasHereButDifferentSize;
uint16_t alywasHereButDifferentSize;
}
当引用时,您会有一个if,它引用了一个或另一个变量
或者,您可以创建一个void*指针,在运行时初始化该指针,指向任意一种类型的变量。第二种情况可以替换为
std::conditional<(SOME_CONSTANT > SOME_VALUE), uint8_t, uint16_t>::type
alywasHereButDifferentSize;
std::conditional SOME\u VALUE),uint8\u t,uint16\u t>::类型
总是不同的大小;
首先,我认为没有。首先:
template <bool>
struct implement_maybe_here
{};
template <>
struct implement_maybe_here<true>
{
int maybe_here;
};
struct my_struct : implement_maybe_here<HAS_MAYBE_HERE>
{
double always_here;
};
模板
结构实现在这里
{};
模板
结构实现在这里
{
int可能在这里;
};
结构我的结构:在这里实现
{
在这里加倍;
};
我不建议这样做,因为它很难维护,而且这里的变量可能很难初始化(但无论采用何种方法,这都会是一团混乱)
请注意,您不能保证implemente\u这里的可能会占用零内存,但是许多编译器实现了这一点
对于第二种情况,使用std::conditional
,正如@ForEveR建议的那样。对于第二种情况,我通常更喜欢将黑客限制在一个位置的typedef:
#if SOME_CONSTANT > SOME_VALUE
typedef uint8_t always_type;
#else
typedef uint16_t always_type;
#endif
然后剩下的代码将始终使用类型
:
struct MyStruct {
// ...
always_type always_here_but_different_size;
// ...
};
如果要使用:
typedef std::conditional<(SOME_CONSTANT > VALUE), uint8_t, uint16_t>::type always_type;
typedef std::conditional VALUE),uint8\u t,uint16\u t>::始终键入;
这也很好——这里的重点不是关于获取所需类型所使用的语法,而是您通常希望为该类型创建一个名称,以便在需要时使用它
至于某物是否存在的情况,有点难说。通常,这样的事情与在构建时启用/禁用某些特性有关。如果是这样,则该类似乎既有与可启用/禁用的功能相关的职责,也有与其他功能相关的职责。这听起来可能违反了单一责任原则,而且可能没有很强的凝聚力。如果是这样的话,它可能表明一个问题在总体设计层面上得到了更好的解决,而不仅仅是您使用的语法
警告:我可能是从公认的最小证据中推断出了相当多的证据——可能比证据真正支持的要多。加上联盟之外的另一个变量,它可以指示正在使用的字段。这很好,但它不是解决方案,因为这里没有定义-代码不会编译。所以,我认为我们根本无法取代ifdef。@ForEveR:当然。人们必须在某些时候使用一些预处理器,比如#ifdef which#define has#u MAYBE#u HERE 1#否则…
,甚至像#define has#u MAYBE(whichere)defined
这样的东西都可以工作。但是,这是以元编程方式将成员添加到类中的标准方法。是的,因此只有预处理器魔术可以替换struct中的#ifdef。因此,我认为这比使用一个“ifdef”的开销更大。@ForEveR:或者可以避免使用#ifdef
,而使用#define
来实现这一目的。我看到大部分注意力都集中在第二种情况,这很好,但实际上我对第一种情况更感兴趣。谢谢你的建议。