Параметры шаблонов шаблонов и шаблоны с переменными параметрами с помощью gcc 4.4 - PullRequest
10 голосов
/ 15 декабря 2011

Я использую gcc 4.4 в Debian squeeze. Рассмотрим следующий код.

#include <map>
#include <string>
using std::map;
using std::string;

// Args lets the user specify additional explicit template arguments
template <typename T,
      template <typename T, typename... Args> class C,
      typename... Args>
C<T, Args...> foo()
{
  C<T, Args...> x;
  return x;
}

int main(void)
{
  map<string, int> a = foo<string, map, int>();
}

Итак, идея в том, что T соответствует string, C соответствует map, а пакет параметров шаблона Args соответствует int. Возможно, у меня неправильный синтаксис, исправьте, если так. В частности, если кто-то хочет, чтобы первый аргумент шаблона в class C соответствовал T, а остальные - пакету параметров шаблона Args, является ли template <typename T, typename... Args> class C правильный синтаксис?

Это дает ошибку

In function 'int main()':
post.cc:18: error: no matching function for call to 'foo()'

Это похоже на вопрос Шаблонные шаблоны Variadic и совершенная пересылка . Этот вопрос предполагает, что это ошибка gcc, но, возможно, я ошибаюсь, полагая, что эти вопросы относятся к одной и той же вещи.

Пожалуйста, будьте нежны. Мое знание шаблонов вариаума менее 12 часов; Я просто пытался переписать старый код C ++, чтобы уменьшить дублирование. Прошло также много времени с тех пор, как я сделал любой C ++. Если есть обходной путь, пожалуйста, дайте мне знать. Спасибо.

РЕДАКТИРОВАТЬ: Обходной путь, предложенный в комментариях Шаблонные шаблоны Variadic и идеальная пересылка от Ise Wisteria работал для меня, что говорит о том, что это та же ошибка. Конечно, я сейчас (а) интересно, насколько хрупок этот обходной путь и (б) почему он работает, и что побудило Исе подумать об этом. Хотя, думаю, только Исе может ответить на последний вопрос. : -)

Ответы [ 2 ]

3 голосов
/ 15 декабря 2011

Как обсуждалось в редактировании, мой вопрос, кажется, щекочет ту же ошибку, что и связанный вопрос, Шаблонные шаблоны Variadic и идеальная пересылка .В частности, обходной путь, приведенный в ссылке, также работает в моем случае.Работающий модифицированный код выглядит следующим образом:

#include <map>
#include <string>
using std::map;
using std::string;

template <typename T,
      template <typename T, typename... Args> class C,
      typename... Args>
struct X
{
  typedef C<T, Args...> type;
};

template <typename T,
      template <typename T, typename... Args> class C,
      typename... Args>
typename X<T, C, Args...>::type foo()
{
  C<T, Args...> x;
  return x;
}

int main(void)
{
  map<string, int> a = foo<string, map, int>();
}
0 голосов
/ 15 декабря 2011

Я не думаю, что параметры шаблона с переменными параметрами могут соответствовать невариантным аргументам в g ++ 4.4, поэтому вам необходимо перегружать свою функцию foo версией без переменных.

Также имейте в виду, что карта на самом деле имеет более двух параметров шаблона и поэтому также не будет соответствовать новой функции foo.

Это дополнение к вашему примеру должно прояснить это:

#include <map>
#include <string>
using std::map;
using std::string;

// Args lets the user specify additional explicit template arguments
template <typename T,
          template <typename T, typename... Args> class C,
          typename... Args>
C<T, Args...> foo() {
  C<T, Args...> x;
  return x;
}

template<typename T, template<typename, typename> class C, typename Arg>
C<T, Arg> foo() {
  return C<T, Arg>();
}

template<typename T, typename... Args> class A {};

template<typename T, typename Arg> class B {};

int main(void) {
  map<string, int> a = foo<string, map, int>(); // fails.
  A<string, int> x = foo<string, A, int>();
  B<string, int> y = foo<string, B, int>();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...