Чистый способ необязательного включения членов в C ++ ctor-initializer

Если у меня есть:

Class MyClass {
public:
MyClass( /* args */ );
private:
someType member0;
someType member1;
// ...
someType memberN;
#if defined(FIRST_COMPILE_CONDITION)
someType condition1Member0;
someType condition1Member1;
// ...
someType condition1MemberN;
#endif
#if defined(SECOND_COMPILE_CONDITION)
someType condition2Member0;
someType condition2Member1;
// ...
someType condition2MemberN;
#endif
};

для некоторого произвольного числа условий компиляции, есть ли чистый способ сделать эквивалент этого (особенно для, возможно, нескольких условий компиляции), не оставляя некоторый постоянный член последним?

MyClass::MyClass( /* args */ ) :
member0( someValue ),
member1( someValue ),
// ...
memberN( someValue ),
#if defined(FIRST_COMPILE_CONDITION)
condition1Member0( someValue ),
condition1Member1( someValue ),
// ...
condition1MemberN( someValue ),
#endif
#if defined(SECOND_COMPILE_CONDITION)
condition2Member0( someValue ),
condition2Member1( someValue ),
// ...
condition2MemberN( someValue ),
#endif
// ...
{
}

Поскольку вышеупомянутое не будет компилироваться в большинстве условий из-за запятой.

Изменить, чтобы уточнить:

Вероятно, следует четко отметить, что someValue предназначен для того, чтобы быть потенциально независимым, произвольным значением, которое может зависеть или не зависеть от аргументов конструктора в каждом используемом случае.

0

Решение

Вы можете поставить запятую перед инициализаторами:

MyClass::MyClass() :
member0( someValue )
,member1( someValue )
// ...
, memberN( someValue )
#if defined(FIRST_COMPILE_CONDITION)
,condition1Member0( someValue )
,condition1Member1( someValue )
// ...
,condition1MemberN( someValue )
#endif
// ...
{
}
3

Другие решения

Лично я стараюсь по возможности избегать директив компилятора (за исключением включения средств защиты), потому что они обычно скрывают проблемы и отражают проблемы дизайна.

Одна проблема дизайна, с которой мы все сталкиваемся, — это специфический для Windows / Linux / Mac код. Существует мало способов справиться с кроссплатформенностью.

Чтобы справиться с этим, я пропускаю директивы компилятора и обращаюсь к нему на уровне Makefile / project (в зависимости от ваших инструментов). Чтобы сделать это здесь, вы можете:

  1. Добавьте метод init_conditional () в класс и вызовите его в конструкторе
  2. Добавьте файлы class_init _…. cpp для каждого условия, каждое со своей реализацией init_conditional ()
  3. Пусть make-файл решит, что компилировать и связывать в

Теперь делать это самостоятельно, но в коде намного чище.

Примечание. Это теряет защиту инициализации по элементам, но является более общим решением проблемы множественной условной компиляции.

2

Я всегда использую следующий способ написать инициализацию:

MyClass::MyClass()
: member0 ( some_value0 )
, member1 ( some_value1 )
// etc
{}

это логически более правильный путь, так как запятая отделяет член от его предшественник, не следующий.

1

Я полагаю, что по этой причине некоторые люди перемещают запятую так, чтобы она находилась перед следующей записью:

member0( someValue ),
member1( someValue )
// ...
, memberN( someValue )
#if defined(FIRST_COMPILE_CONDITION)
, condition1Member0( someValue )
, condition1Member1( someValue )

Но это невероятно некрасиво.

0

Просто поменяйте местами запятую логику:

MyClass::MyClass() :
member0( someValue ),
member1( someValue ),
// ...
memberN( someValue )
#if defined(FIRST_COMPILE_CONDITION)
,condition1Member0( someValue )
,condition1Member1( someValue )
// ...
,condition1MemberN( someValue )
#endif
#if defined(SECOND_COMPILE_CONDITION)
,condition2Member0( someValue )
,condition2Member1( someValue )
// ...
,condition2MemberN( someValue )
#endif
// ...
{
}

Обратите внимание на удаление запятой после первого членаN

0

Когда вы можете или можете использовать C ++ 11, это становится действительно легко

Class MyClass {
public:
MyClass();
private:
someType member0 = someValue;
someType member1 = someValue;
// ...
someType memberN;
#if defined(FIRST_COMPILE_CONDITION)
someType condition1Member0 = someValue;
someType condition1Member1 = someValue;
// ...
someType condition1MemberN = someValue;
#endif
#if defined(SECOND_COMPILE_CONDITION)
someType condition2Member0 = someValue;
someType condition2Member1 = someValue;
// ...
someType condition2MemberN = someValue;
#endif
};

Реальное большое преимущество в том, что вам не нужно заботиться о нескольких конструкторах.
Однако вы можете достичь этого и с другими подходами.

0