Йоу. Есть следующее определение шаблонного класса:
template<
class Attribute1,
class Attribute2 = void,
class Attribute3 = void,
class Attribute4 = void
>
class Entity {
public:
typename Attribute1::Type _attribute1;
typename Attribute2::Type _attribute2;
typename Attribute3::Type _attribute3;
typename Attribute4::Type _attribute4;
};
При таком определении класс можно специализировать только четырьмя параметрами, каждый из которых должен быть классом, в котором определено имя Type. Число параметров 4 взято для примера. При реальном использовании шаблонных параметров может быть до 16.
Теперь о том, что хочется. Хочется, чтобы те члены _attributeN, для которых соответствующий шаблонный параметр AttributeN является void, убирались из определения класса. Иными словами, хочется, чтобы при специализации вида Entity< ConcreteAttribute1 >, код компилировался, и в классе был единственный член _attribute1; чтобы при специализации вида Entity< ConcreteAttribute1, ConcreteAttribute2 > в классе были только члены _attribute1 и _attribute2 и т.д. Возможно ли это осуществить каким-либо образом?
P.S.: несмотря на то, что смысл задачи состоит в описании кортежа, заменить её на использование std::tuple по некоторым причинам невозможно.
Здравствуйте, Van_Der_Lokken, Вы писали:
V_D>P.S.: несмотря на то, что смысл задачи состоит в описании кортежа, заменить её на использование std::tuple по некоторым причинам невозможно.
Раз вы знакомы с boost::tuple, то можете взять идею из реализации.
Здравствуйте, Bell, Вы писали:
B>Банальнейшее решение в лоб: ...
Спасибо. Это простое и хорошее решение, но не идеальное. Я тоже думал о варианте с наследованием, но мне он не совсем понравился по той причине, что Entity перестаёт быть aggregate-классом (то есть, у Entity вообще не оказывается ни конструктора, ни aggregate-инициализации, что неприятно). Но если никто не предложит ничего лучше, то именно это решение я и использую.
Re: Возможно ли убрать член класса в зависимости от параметр
Здравствуйте, Van_Der_Lokken, Вы писали:
V_D>Йоу. Есть следующее определение шаблонного класса:
V_D>При таком определении класс можно специализировать только четырьмя параметрами, каждый из которых должен быть классом, в котором определено имя Type. Число параметров 4 взято для примера. При реальном использовании шаблонных параметров может быть до 16.
V_D>Теперь о том, что хочется. Хочется, чтобы те члены _attributeN, для которых соответствующий шаблонный параметр AttributeN является void, убирались из определения класса. Иными словами, хочется, чтобы при специализации вида Entity< ConcreteAttribute1 >, код компилировался, и в классе был единственный член _attribute1; чтобы при специализации вида Entity< ConcreteAttribute1, ConcreteAttribute2 > в классе были только члены _attribute1 и _attribute2 и т.д. Возможно ли это осуществить каким-либо образом?
к варианту Bell можно добавить вариант со специализацией, если нет идеологических предубеждений против макросов.
пример здесь
Здравствуйте, Van_Der_Lokken, Вы писали:
V_D>Теперь о том, что хочется. Хочется, чтобы те члены _attributeN, для которых соответствующий шаблонный параметр AttributeN является void, убирались из определения класса. Иными словами, хочется, чтобы при специализации вида Entity< ConcreteAttribute1 >, код компилировался, и в классе был единственный член _attribute1; чтобы при специализации вида Entity< ConcreteAttribute1, ConcreteAttribute2 > в классе были только члены _attribute1 и _attribute2 и т.д. Возможно ли это осуществить каким-либо образом?
Нужно ли уметь пропускать атрибут в центре списка? Если нет, то можно сделать 16 частичных специализаций...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Возможно ли убрать член класса в зависимости от парам
Здравствуйте, Van_Der_Lokken, Вы писали:
V_D>Здравствуйте, Bell, Вы писали:
B>>Банальнейшее решение в лоб: ...
V_D>Спасибо. Это простое и хорошее решение, но не идеальное. Я тоже думал о варианте с наследованием, но мне он не совсем понравился по той причине, что Entity перестаёт быть aggregate-классом (то есть, у Entity вообще не оказывается ни конструктора, ни aggregate-инициализации, что неприятно). Но если никто не предложит ничего лучше, то именно это решение я и использую.
Здесь без наследования не обойтись.
Для себя решал подобную задачу и пришёл к следующую решению (используется как базовое для весокоуровневых компонентов)
template < class, size_t >
struct slot;
template < size_t I >
struct slot< Loki::NullType, I >
{
///typedef Loki::NullType
value_type;
///
value_type
value;
};
template < typename T, typename U, size_t I >
struct slot< Loki::Typelist< T, U >, I > : public slot< U, I + 1 >
{
///typedef T
value_type;
///
value_type
value;
};
Аналогичное Loki::GenLinearHierarchy.
Можно посмотреть здесь здесь файл z3d/slot.hpp
Re[2]: Возможно ли убрать член класса в зависимости от парам
Здравствуйте, Erop, Вы писали:
E>Нужно ли уметь пропускать атрибут в центре списка? Если нет, то можно сделать 16 частичных специализаций...
На самом деле, не нужно. И этот вариант с кучей специализаций под разное число параметров приходит в голову самым первым. Он плох тем, что появляется чёртова прорва практически одинакового кода. И неизбежный в этом случае copy-paste, как известно, является первым признаком того, что код организован неудачно.
Re[2]: Возможно ли убрать член класса в зависимости от парам
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, Van_Der_Lokken, Вы писали:
V_D>>P.S.: несмотря на то, что смысл задачи состоит в описании кортежа, заменить её на использование std::tuple по некоторым причинам невозможно.
NB>по каким? std::tuple легко переписывается своими силами с нужной функциональностью.
Сам по себе std::tuple не годится, так как никто не гарантирует, что элементы кортежа будут расположены в памяти в том же порядке, в каком были указаны в списке параметров шаблона, и что между ними не окажется padding-байтов. А та структура данных, что мне нужна, должна удовлетворять этим требованиям. Скажем, в моём компиляторе sizeof( std::tuple<uint32_t> ) == 8. Если я всё правильно понимаю, в реализации кортежа 4 байта всегда обязательно уходит на некий "хвостовой" элемент. В моём случае неприемлемо.
Re[3]: Возможно ли убрать член класса в зависимости от парам
Здравствуйте, Van_Der_Lokken, Вы писали:
V_D>>>P.S.: несмотря на то, что смысл задачи состоит в описании кортежа, заменить её на использование std::tuple по некоторым причинам невозможно.
NB>>по каким? std::tuple легко переписывается своими силами с нужной функциональностью.
V_D>Сам по себе std::tuple не годится, так как никто не гарантирует, что элементы кортежа будут расположены в памяти в том же порядке, в каком были указаны в списке параметров шаблона, и что между ними не окажется padding-байтов. А та структура данных, что мне нужна, должна удовлетворять этим требованиям. Скажем, в моём компиляторе sizeof( std::tuple<uint32_t> ) == 8. Если я всё правильно понимаю, в реализации кортежа 4 байта всегда обязательно уходит на некий "хвостовой" элемент. В моём случае неприемлемо.
никаких хвостовых элементов в тупле нет.
список типов известен на момент компиляции, поэтому в нем нет необходимости.
возможно, в конце наследования есть пустая структура, но нормальные компиляторы умеют делать EmptyBaseOptimisation.
если твой не может, то "std::tuple легко переписывается своими силами". в своем велосипеде крайним делается тупл из одного элемента, и все дела.
Re[3]: Возможно ли убрать член класса в зависимости от парам
Здравствуйте, Van_Der_Lokken, Вы писали:
V_D>На самом деле, не нужно. И этот вариант с кучей специализаций под разное число параметров приходит в голову самым первым. Он плох тем, что появляется чёртова прорва практически одинакового кода. И неизбежный в этом случае copy-paste, как известно, является первым признаком того, что код организован неудачно.
генерить одинаковый код можно поручить макросам...
Но в целом мне кажется, что сама по себе задача какая-то подозрительная. Зачем это всё в целом вообще надо?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском