У меня есть куча атрибутов, которые могут быть либо NOP, либо иметь состояние. Требование к ним - не иметь никакого размера, когда пользователю не нужен атрибут, но при этом содержать определенные методы. Пример:
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)
{
/* ... */
}
}
};
Это работает, но теперь есть проблема: размер атрибутов NOP, хотя и является пустыми классами, не равен 0, что означает, что 100 пустых атрибутов добавляют много неиспользуемого пространства в MyUberClass.
Есть ли способ избежать этого и добавить / удалить переменные-члены на основе параметра шаблона?
EDIT:
Насколько я знаю, пустые классы не имеют размера 0. Когда я пытаюсь сделать следующее, я получаю sizeof (B) == 4.
template <typename T>
class A
{
};
class B : public A<int>, public A<double>, public A<char>, public A<long>, public A<bool>
{
};