Если у меня есть:
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
предназначен для того, чтобы быть потенциально независимым, произвольным значением, которое может зависеть или не зависеть от аргументов конструктора в каждом используемом случае.
Вы можете поставить запятую перед инициализаторами:
MyClass::MyClass() :
member0( someValue )
,member1( someValue )
// ...
, memberN( someValue )
#if defined(FIRST_COMPILE_CONDITION)
,condition1Member0( someValue )
,condition1Member1( someValue )
// ...
,condition1MemberN( someValue )
#endif
// ...
{
}
Лично я стараюсь по возможности избегать директив компилятора (за исключением включения средств защиты), потому что они обычно скрывают проблемы и отражают проблемы дизайна.
Одна проблема дизайна, с которой мы все сталкиваемся, — это специфический для Windows / Linux / Mac код. Существует мало способов справиться с кроссплатформенностью.
Чтобы справиться с этим, я пропускаю директивы компилятора и обращаюсь к нему на уровне Makefile / project (в зависимости от ваших инструментов). Чтобы сделать это здесь, вы можете:
Теперь делать это самостоятельно, но в коде намного чище.
Примечание. Это теряет защиту инициализации по элементам, но является более общим решением проблемы множественной условной компиляции.
Я всегда использую следующий способ написать инициализацию:
MyClass::MyClass()
: member0 ( some_value0 )
, member1 ( some_value1 )
// etc
{}
это логически более правильный путь, так как запятая отделяет член от его предшественник, не следующий.
Я полагаю, что по этой причине некоторые люди перемещают запятую так, чтобы она находилась перед следующей записью:
member0( someValue ),
member1( someValue )
// ...
, memberN( someValue )
#if defined(FIRST_COMPILE_CONDITION)
, condition1Member0( someValue )
, condition1Member1( someValue )
Но это невероятно некрасиво.
Просто поменяйте местами запятую логику:
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
Когда вы можете или можете использовать 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
};
Реальное большое преимущество в том, что вам не нужно заботиться о нескольких конструкторах.
Однако вы можете достичь этого и с другими подходами.