Расширение пакета параметров шаблона variadic для вызовов функций - PullRequest
17 голосов
/ 04 августа 2011

Я ищу что-то подобное:

template< typename T>  
void func(T t)
{
}

template< typename... Parms> 
void anyFunc( Parms... p)
{
    func<Parms>(p)... ;  //error 
    func(p)... ;         //error 
}

Если расширение пакета параметров выполняется внутри другого вызова функции, оно работает:

template< typename T>
int some(T t)
{}

template< typename... Parms>
void func(Parms ...p)
{}

template< typename... Parms>
void somemore(Parms... p)
{
   func( some(p)...);
}

int main() 
{
 somemore(1,2,3,4,10,8,7, "Hallo");
}

Расширение пакета параметров также будет работатьдля списка инициализаторов базового класса.

Есть ли какое-либо решение, которое также будет работать для функций, которые будут возвращать 'void'.Приведенный выше обходной путь не сработает, хотя вызовы функций, возвращающие void внутри списка параметров, никогда не сработают.

Есть идеи?

Ответы [ 2 ]

10 голосов
/ 04 августа 2011

К сожалению, как вы заметили, расширение пакета параметров допустимо только в определенных контекстах, где синтаксический анализатор ожидает разделенный запятыми список записей - контексты, где запятая является только синтаксическим разделителем, а не оператором запятой.Это, возможно, недостаток в текущем тексте.

Уродливый обходной путь:

func((some(p), 0)...);

Обратите внимание, что порядок вычисления аргументов функции и, следовательно, порядок вызовов some,не указано, поэтому вы должны быть осторожны с любыми побочными эффектами.

5 голосов
/ 05 августа 2011

Как насчет небольшого вспомогательного класса:

template <typename Func, typename A, typename ...Args> struct Caller
{
  static void call(Func & f, A && a, Args && ...args)
  {
    f(std::forward<A>(a));
    Caller<Func, Args...>::call(f, std::forward<Args>(args)...);
  }
};

template <typename Func, typename A> struct Caller<Func, A>
{
  static void call(Func & f, A && a)
  {
    f(std::forward<A>(a));
  }
};

template <typename Func, typename ...Args>
void Call(Func & f, Args && ...args)
{
  Caller<Func, Args...>::call(f, std::forward<Args>(args)...);
}

Затем в коде клиента можно указать следующее:

void foo(A);
Call(foo, a1, a2, a3);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...