2011-12-15 14 views
9

Estoy usando gcc 4.4 en Debian squeeze. Considera el siguiente código.Parámetros de plantilla de plantilla y plantillas variadic con 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>(); 
} 

Por lo tanto, la idea aquí es que T partidos string, C los partidos map, y el parámetro de paquete de plantillas Args partidos int. Es posible que tenga un poco de sintaxis, por favor corríjalo si es así. En particular, si uno quiere el primer argumento de plantilla en class C para que coincida con T y el resto para que coincida con el paquete de parámetros de plantilla Args, ¿es template <typename T, typename... Args> class C la sintaxis correcta?

Esto da el error

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

Esto parece ser similar a la pregunta Variadic template templates and perfect forwarding. Esa pregunta sugiere que este es un error de gcc, pero tal vez estoy equivocado al pensar que estas preguntas son más o menos lo mismo.

Sea gentil. Mi conocimiento de plantillas variadic es menos de 12 horas; Solo intentaba reescribir algún código antiguo de C++ para reducir la duplicación. También ha pasado un tiempo desde que hice C++. Si hay una solución alternativa, házmelo saber. Gracias.

EDITAR: La solución sugerida en los comentarios de Variadic template templates and perfect forwarding por Ise Wisteria funcionó para mí, lo que sugiere que este es el mismo error. Por supuesto, ahora estoy en (a) preguntándome qué tan frágil es esta solución y (b) por qué funciona, y qué motivó a Ise a pensar en ello. Aunque supongo que solo Ise puede responder el último bit. :-)

+0

El código se compila en g ++ 4.7. Debería ser un error. – kennytm

+0

@KennyTM: Gracias. Eso significa que no necesito informarlo, ¿verdad? –

+0

Derecha. ~~~~~~~~~~ – kennytm

Respuesta

3

Como se discutió en las ediciones, mi pregunta parece cosquillas el mismo fallo ya que la cuestión vinculada, Variadic template templates and perfect forwarding. En particular, la solución dada allí en un enlace también funciona en mi caso. El código modificado que funciona es el siguiente:

#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

No creo que los parámetros de la plantilla variadic puedan coincidir con argumentos no variados en g ++ 4.4, por lo que necesita sobrecargar su función foo con una versión no variadica.

También tenga en cuenta que el mapa en realidad tiene más de dos parámetros de plantilla, y por lo tanto tampoco coincidirá con la nueva función foo.

Esta adición a su ejemplo debe aclarar que:

#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

No, las plantillas variadic son explícitamente capaces de coincidir con plantillas no variantes. – Xeo

+0

@Xeo: No en g ++ 4.4 – masaers

+0

Bueno, eso es un error. Estoy hablando de lo que dice el estándar."No creo que los parámetros de plantillas variadas puedan coincidir con argumentos no variados" parecía sugerir que usted piensa que este es el caso en general. – Xeo

Cuestiones relacionadas