2012-06-25 1 views
2

Я не уверен, ответил ли этот вопрос. Но вот он идет:Функция C++: шаблоны Variadic без аргументов

мне было интересно, если это возможно, чтобы сделать что-то вроде

template<typename...classes> 
void createObject(){ 

    //pass each type into my template function wich takes one type only. 

} 

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

Любое предложение?

Примечание: GCC 4.6.2

+1

Можете ли вы лучше узнать, что должен делать fuction и что он должен вернуть? Имеют ли возвращенные объекты какой-то общий тип между ними? –

ответ

3
template<typename...> 
struct caller; 

template<typename T, typename...Rest> 
struct caller<T, Rest...> 
{ 
    static void call() 
    { 
     create<T>(); 
     caller<Rest...>::call(); 
    } 
}; 

template<> 
struct caller<> 
{ 
    static void call() 
    { 
    } 
}; 

//since you've not mentioned the return type, I'm assuming it to be void 
//if it is not void, then I don't know what you're going to return, and HOW! 
template<typename...classes> 
void createObject(){ 
     caller<classes...>::call(); 
} 

Демонстрация: http://ideone.com/UHY8n


Альтернативный (сокращенный вариант):

template<typename...> 
struct typelist{}; 

template<typename T, typename ... Rest> 
void call(typelist<T,Rest...>) 
{ 
    create<T>(); 
    call(typelist<Rest...>()); 
}; 

void call(typelist<>) { } 

template<typename...classes> 
void createObject(){ 
     call(typelist<classes...>()); 
} 

Демонстрация: http://ideone.com/cuhBh

+1

Да, это должно быть пусто. Не могли бы вы рассказать о том, что вы делаете в точности. Я понимаю, что он становится рекурсивным. Но не понимаю, как это сделать. Вы, кажется, дважды называете «звонок». – Sidar

+0

@ Сидар: поиск метапрограммирования на C++; см. несколько примеров, так как это поможет вам начать с * этого, что облегчит мне объяснение, что я сделал. В противном случае, я должен потратить много времени, набрав здесь мини-учебник (чего я не могу сделать, поскольку я сейчас нахожусь в офисе). – Nawaz

+0

Хорошо. Спасибо за ваши ответы. – Sidar

2

Один из способов заключается в использовании следующей функции для расширения вызовов:

template <typename... Ts> 
void swallow(Ts&&...) { 
} 

Я предполагаю, что вы хотите, чтобы вызвать следующую функцию:

template <typename T> 
void create() { 
} 

В этом случае, вы будете нуждаться в вспомогательная функция, которая преобразует пустоту create в один, который возвращает что-то, так что мы можем расширить его в Arg-список swallow (если create функция уже непусто, то этот дополнительный шаг не требуется):

template <typename T> 
int createHelper() { 
    create<T>(); 
    return 0; 
} 

template<typename... Ts> 
void createObject(){ 
    swallow(createHelper<Ts>()...); 
} 
+0

Я принимаю Ts && ... пересылает следующий тип? Но это не совсем рекурсивно, не так ли? – Sidar

+0

Нет, это не рекурсивно. Точка arg-списка 'swallow' заключается в том, что она привязывается ко всему (мы фактически ничего не делаем с args, как вы можете видеть, весь вызов будет оптимизирован). Это просто простой способ расширения пакетов шаблонов параметров в определенных ситуациях. – mitchnull

+0

Я не полностью понимаю концепцию. Но спасибо за ваш вклад. Я уже решил проблему до сих пор. Позже я мог бы вернуться к этому. – Sidar

 Смежные вопросы

  • Нет связанных вопросов^_^