2011-12-15 6 views
9

Я использую gcc 4.4 на сжатии Debian. Рассмотрим следующий код.Шаблонные параметры шаблона и вариативные шаблоны с gcc 4.4

#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 template templates and perfect forwarding. Этот вопрос предполагает, что это ошибка gcc, но, может быть, я ошибаюсь, думая, что эти вопросы касаются одного и того же.

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

EDIT: Обходной путь, предложенный в комментариях Variadic template templates and perfect forwarding от Ise Wisteria, работал на меня, что говорит о том, что это та же ошибка. Конечно, я сейчас (а) интересуется, насколько хрупким это обходное решение, и (б) почему он работает, и что побудило Исе думать об этом. Хотя я думаю, что только Ise может ответить на последний бит. :-)

+0

Код компилируется на g ++ 4.7. Должна быть ошибка. – kennytm

+0

@KennyTM: Спасибо. Это означает, что мне не нужно сообщать об этом, верно? –

+0

Право. ~~~~~~~~~~ – kennytm

ответ

3

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

#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

Я не думаю, что переменные параметры шаблона могут соответствовать невариантным аргументам в 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>(); 
} 
+0

Нет, вариативные шаблоны явно могут соответствовать невариантным шаблонам. – Xeo

+0

@Xeo: Не на g ++ 4.4 – masaers

+0

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