Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在编译时组合成员_C++_Templates_Metaprogramming - Fatal编程技术网

C++ 在编译时组合成员

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

我有一堆属性,可以是NOP,也可以是state。当用户不需要属性,但仍然包含某些方法时,它们的要求是没有任何大小。例如:

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;
}