У меня есть набор методов, используемых для создания и инициализации набора объектов. Все они выглядят почти одинаково, за исключением количества аргументов, которые передаются в функцию Init:
ObjectType* CreateObjectType(Arg1 a1, Arg2 arg2, ... ArgN aN)
{
ObjectType* object = new ObjectType();
[...]
object->Init(this, a1, a2, ..., aN);
[...]
return object;
}
Обратите внимание, что аргументы не должны использоваться где-либо, кроме как для передачи в функцию Init.
Я хотел бы найти способ реализовать все это без дублирования кода для каждого типа объекта.
Я пробовал использовать макросы с переменным числом аргументов и получил следующий (неверный) результат:
#define CREATE_OBJECT_IMPL(ObjectType, ...) \
ObjectType* Create##ObjectType##(__VA_ARGS__) \
{ \
ObjectType* object = new ObjectType(); \
[...]
object->Init(this, ##__VA_ARGS__); \
[...]
return object; \
}
// This is the result I am trying to achieve :
CREATE_OBJECT_IMPL(MyFirstObject, bool, float)
CREATE_OBJECT_IMPL(MySecondObject, int)
CREATE_OBJECT_IMPL(MyThirdObject)
Теперь в этой реализации я дважды использовал VA_ARGS, оба раза неправильно:
В первом случае я хочу иметь список аргументов с указанными мной типами (Arg1 a1, Arg2 a2 ...)
Во втором случае я хочу назвать эти аргументы их именами (Init (a1, a2 ...)).
Я пробовал использовать вариативные шаблоны:
template< typename ObjectType, typename... Args >
ObjectType* CreateObject(Args args)
{
ObjectType* object = new ObjectType();
[...]
object->Init(this, args);
[...]
return object;
}
#define CREATE_OBJECT_IMPL(ObjectType, ...) \
ObjectType* Create##ObjectType##(__VA_ARGS__) \
{ \
return CreateObject<ObjectType, __VA_ARGS__>(__VA_ARGS__); \
}
... но это, похоже, тоже не работает, я получаю следующую ошибку в строке определения шаблона:
ошибка C2143: синтаксическая ошибка: отсутствует ',' перед '...'
ошибка C2065: 'Args': необъявленный идентификатор
Я использую VS2012.
Я все еще мог написать N похожих макросов для каждого количества аргументов, однако мне было интересно, есть ли способ получить тот же результат без дублирования кода?
template< typename ObjectType, typename... Args > ObjectType* CreateObject(Args... args);
. Но вам понадобится некоторый контекст, чтобы расширить пакет аргументов. - person jrok   schedule 14.08.2013