Функции с вариационными шаблонами - PullRequest
2 голосов
/ 09 января 2012

Я хочу написать шаблон функции, который может принимать переменное число аргументов шаблона, и просто распечатать typeid (). Name () параметров типа. Я могу сделать что-то подобное, используя статические функции внутри шаблонов классов, следующим образом:

template<typename...>
struct foo;

template<typename H, typename... T>
struct foo<H, T...> {
  static void print() {
    std::cout << typeid(H).name() << ", ";
    foo<T...>::print();
  }
};

template<typename H>
struct foo<H> {
  static void print() {
    std::cout << typeid(H).name() << "\n";
  }
};

int main(void)
{
  foo<int, float>::print();
  return 0;
}

Однако я не могу сделать следующее:

template<typename H, typename... T>
void print() {
  std::cout << typeid(H).name() << ", ";
  print<T...>();
}
int main(void)
{
  print<int, float>();
  return 0;
}

Я попытался добавить следующие «базовые» случаи:

template<typename H>
void print();

и

void print();

Ни сработало. Как мне написать такой шаблон функции?

Ответы [ 3 ]

3 голосов
/ 09 января 2012

FWIW, я мог бы получить следующий код для компиляции с Clang 3.1 и GCC 4.5.1 :

#include <typeinfo>
#include <iostream>

template<class T>
void print(){
  std::cout << typeid(T).name();
}

template<typename H, typename T, typename... R>
void print(){
  std::cout << typeid(H).name() << ", ";
  print<T, R...>();
}

int main(){
  print<int, float>();
}
1 голос
/ 10 января 2012
template<typename H>
void print();

Это не сработает, потому что оно неоднозначно с вариационной перегрузкой: оба могут быть вызваны с одним аргументом шаблона.

void print();

Это не работает, потому что в вашей переменной print вы вызываете print<T...>, который может соответствовать только шаблону print, а не обычной функции (даже когда T... раскрывается в пустой список аргументов, звонок будет print<>(), а не print().)

Одним из решений является изменение вашего вариационного регистра, чтобы он принимал не менее двух аргументов:

template<typename H, typename T1, typename... TRest>
void print() {
  std::cout << typeid(H).name() << ", ";
  print<T1, T...>();
}

Теперь ваш шаблон с одним аргументом print должен быть правильно выбран в нижней части рекурсии.

Я думаю следующее должно работать в C ++ 11 как базовый случай с нулевым аргументом, но я не мог заставить gcc 4.6 принять его:

template<> void print();
0 голосов
/ 10 января 2012

В качестве альтернативы вы можете сделать это:

void print() {/*...*/} 

template<typename X>   void print() {/*...*/} 

template<typename X, typename Y>   void print() {/*...*/} 

int main()
{
  print();
  print<int>();
  print<int,double>();

  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...