2011-02-09 15 views
13

El código siguiente genera un error de compilación en Xcode:parámetros de plantilla implícitos

template <typename T> 
struct Foo 
{ 
    Foo(T Value) 
    { 
    } 
}; 

int main() 
{ 
    Foo MyFoo(123); 
    return 0; 
} 

error: missing template arguments before 'MyFoo'

Cambio Foo MyFoo(123); a Foo<int> MyFoo(123); corrige el problema, pero no deben ser el compilador capaz de averiguar la adecuada ¿tipo de datos?

¿Es esto un error del compilador, o estoy malinterpretando los parámetros implícitos de la plantilla?

Respuesta

11

El constructor en teoría, podría inferir el tipo del objeto que está construyendo, pero la declaración:

Foo MyFoo(123); 

es la asignación de espacio temporal para MyFoo y hay que conocer el tipo completo del MyFoo el fin de conocer Cuánto espacio se necesita.

Si quiere evitar tener que escribir (es decir, con los dedos) el nombre de una plantilla especialmente compleja, considere el uso de un typedef:

typedef std::map<int, std::string> StringMap; 

O en C++ 0x se puede utilizar la palabra clave auto tener la la inferencia del tipo de uso del compilador, aunque muchos argumentarán que conduce a un código menos legible y propenso a errores, yo mismo entre ellos. ; P

+5

si se pudiera inferir el tipo, se podría inferir el espacio. –

+6

Puede inferir el tipo para la llamada al constructor, pero no para el espacio de almacenamiento. Si define una variable como simplemente 'Foo', ¿puede contener tanto' Foo 'como' Foo '? ¿O siempre sabe que es secretamente un 'Foo ' en el corazón de los corazones? Si la variable fuera 'const', entonces podría implementarse, ya que el valor no podría reasignarse, pero luego tendríamos diferentes reglas léxicas para' const T' vs 'T' y se producirían grandes estragos. –

7

compilador puede averiguar el tipo de parámetro de plantilla sólo para funciones de plantilla, no para las clases/estructuras

+3

Después de todo, hay una razón para la función 'std :: make_pair (T t, U u)' aunque ya tenemos la clase 'std :: pair '. –

2

No es un insecto, es que no existe función. Debe especificar por completo los argumentos de la plantilla de clase/estructura durante la creación de instancias, siempre, los tipos no se deducen, ya que pueden ser para plantillas de funciones.

2

compilador puede deducir la tal caso, el argumento de plantilla:

template<typename T> 
void fun(T param) 
{ 
    //code... 
} 

fun(100); //T is deduced as int; 
fun(100.0); //T is deduced as double 
fun(100.0f); //T is deduced as float 

Foo<int> foo(100); 
fun(foo); //T is deduced as Foo<int>; 

Foo<char> bar('A'); 
fun(bar); //T is deduced as Foo<char>; 

deducción argumento realidad plantilla es un tema enorme. Leer este artículo en el ACU:

The C++ Template Argument Deduction

0

Se tiene mucho sentido, es así, como Foo no es una clase, sólo se Foo<T> donde T es un tipo.

En C++ 0x puede usar auto, y puede crear una función para que sea un Foo, llamémoslo foo (minúscula f). De allí tendría que hacer

template<typename T> Foo<T> foo(int x) 
{ 
    return Foo<T>(x); 
} 

auto myFoo = foo(55); 
+0

Quizás quiso decir: "template Foo foo (T x)"? –

2

En C++ 11 puede utilizar decltype:

int myint = 123; 
Foo<decltype(myint)> MyFoo(myint); 
Cuestiones relacionadas