C++ 在编译时组合成员
我有一堆属性,可以是NOP,也可以是state。当用户不需要属性,但仍然包含某些方法时,它们的要求是没有任何大小。例如:C++ 在编译时组合成员,c++,templates,metaprogramming,C++,Templates,Metaprogramming,我有一堆属性,可以是NOP,也可以是state。当用户不需要属性,但仍然包含某些方法时,它们的要求是没有任何大小。例如: struct AttributeATag {}; /* The template used when AttributeATag is not specified */ template <typename T> class AttributeA { public: void foo(uint32_t v) { // Nop, d
struct AttributeATag {};
/* The template used when AttributeATag is not specified */
template <typename T>
class AttributeA
{
public:
void foo(uint32_t v)
{
// Nop, do nothing
}
enum
{
HasAttributeA = false
};
};
/* The template specialization used when AttributeATag is specified */
template <>
class AttributeA<AttributeATag>
{
public:
void foo(uint32_t v)
{
this->omgVariable = v;
}
enum
{
HasAttributeA = true
};
protected:
int omgVariable;
};
template <typename ATag>
class MyUberClass : public AttributeA<ATag>
{
// This class now has omgVariable or not, depending on ATag and it
// has either a NOP method or one which actually does something
void doSomething()
{
if (AttributeA<ATag>::HasAttributeA)
{
/* ... */
}
}
};
struct AttributeATag{};
/*未指定AttributeTag时使用的模板*/
模板
类属性a
{
公众:
void foo(uint32_t v)
{
//不,什么也不做
}
枚举
{
HasAttributeA=false
};
};
/*指定AttributeTag时使用的模板专用化*/
模板
类属性a
{
公众:
void foo(uint32_t v)
{
这->omgVariable=v;
}
枚举
{
HasAttributeA=true
};
受保护的:
国际变量;
};
模板
类MyUberClass:公共属性a
{
//这个类现在是否具有omgVariable,取决于ATag和它
//有一个NOP方法或者一个实际做某事的方法
无效剂量测定法()
{
if(AttributeA::HasAttributeA)
{
/* ... */
}
}
};
这是可行的,但现在有一个问题:NOP属性的大小虽然是空类,但不是0,这意味着100个空属性会为MyUberClass添加大量未使用的空间
有没有办法避免这种情况,并根据模板参数添加/删除成员变量
编辑: 据我所知,空类的大小不是0。当我尝试下面的方法时,我得到sizeof(B)==4
模板
甲级
{
};
B类:公共A、公共A、公共A、公共A、公共A
{
};
在本测试中:
#include <iostream>
struct g{};
int main()
{
std::cout << sizeof(g) << std::endl;
}
#包括
结构g{};
int main()
{
std::cout因为您使用AttributeA
作为基类,所以几乎每个编译器都会使用“空基类优化”来确保空基类在子类中不使用任何空间,即使基类的大小不是零。我相信这里没有问题
每个类(基类/子类)必须至少占用一个字节(如果编译器填充所有内容,则可能占用四个字节),但空基类(几乎在所有情况下)不会使子类的大小增加到超出它们本来的大小。空类的最小大小为1字节,而不管有多少个(空)类是否继承。
在您的示例中,类B
将具有最小的实现定义大小(在您的示例中似乎是4个字节),无论您是从其他类继承还是不继承
这是必需的,这样任何空的类
对象都可以有一个唯一的地址。对此无能为力。AttributeA
只有在ATag=AttributeTag
时才会有大小。其余的情况将仅为空类。这个100
数字来自何处?我看不出任何问题。请把你的问题弄清楚。100只是为了夸大问题。除了一门课以外的东西?那会是什么?@HowieHowitzer我的答案的结尾恐怕是什么。也许是另一种设计,但那没什么帮助。对不起。我只是用MSVC 10和sizeof(B)运行了我的编辑(见我的帖子)在版本中编译时仍然返回4。您确定这是优化了吗?我认为这是我的编译器的问题。它应该应用空基类优化,但出于某些原因,MSVC10仅对第一个基类执行此操作,并为其他基类添加1字节。与sizeof(A)不同==1。这意味着,使用我的编译器(MSVC10),空类的大小为1字节,因此使用sizeof(B)==4,很明显,空类确实增加了B的大小。
#include <iostream>
struct g{};
int main()
{
std::cout << sizeof(g) << std::endl;
}