2011-02-09 15 views
13

Poniższy kod generuje błąd kompilacji w Xcode:niejawne Parametry szablonu

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

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

error: missing template arguments before 'MyFoo'

Zmiana Foo MyFoo(123); do Foo<int> MyFoo(123); rozwiązuje problem, ale nie powinna kompilator być w stanie dowiedzieć się odpowiedni typ danych?

Czy jest to błąd kompilatora, czy też nieporozumienia niejawne parametry szablonu?

Odpowiedz

11

Konstruktor mógłby teoretycznie wywnioskować typ obiektu to buduje, ale stwierdzenie:

Foo MyFoo(123); 

przeznacza tymczasową przestrzeń dla MyFoo i musi znać doskonale wykwalifikowaną typ MyFoo w celu poznania ile miejsca potrzeba.

Jeśli chcesz uniknąć pisania (tj palców) nazwę szczególnie skomplikowanej matrycy, należy rozważyć użycie typedef:

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

Albo w C++ 0x można użyć słowa kluczowego auto mieć wnioskowanie na temat użycia kompilatora - choć wielu będzie argumentować, że prowadzi to do mniej czytelnego i podatnego na błędy kodu, ja sam wśród nich. ; P

+5

jeśli mogłoby to wywnioskować typ, może wnioskować przestrzeń. –

+6

Może określić typ wywołania konstruktora, ale nie dla miejsca do przechowywania. Jeśli zdefiniujesz zmienną jako po prostu 'Foo', czy może ona zawierać zarówno' Foo 'i' Foo '? Czy może zawsze wie, że w głębi serca jest "Foo "? Gdyby zmienna była "const", to mogłaby zostać zaimplementowana, ponieważ nie można było zmienić jej wartości, ale wtedy mielibyśmy różne reguły leksykalne dla 'const T' vs' T' i nastąpiłoby wielkie spustoszenie. –

7

kompilator może dowiedzieć się typ parametru szablonu tylko dla matrycy, funkcji, nie dla klas/kodowanym

+3

Wszakże istnieje przyczyna funkcji 'std :: make_pair (T t, Uu)' chociaż mamy już klasę 'std :: pair '. –

2

To nie jest błąd, to nieistniejące cecha. Musisz w pełni określić argumenty szablonu klasy/struktury podczas tworzenia instancji, zawsze typy nie są wnioskowane, ponieważ mogą być dla szablonów funkcji.

2

Compiler można wywnioskować szablon argumentu taką sprawę:

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>; 

Właściwie szablon odliczenie argument jest ogromny temat. Przeczytaj ten artykuł w ACCU:

The C++ Template Argument Deduction

0

To sprawia, że ​​wiele sensu, że jest tak, jak Foo nie jest klasa, tylko Foo<T> gdzie T jest typem.

W C++ 0x możesz użyć auto, a możesz utworzyć funkcję, która sprawi, że będziesz Foo, nazwijmy to foo (małe litery f). Wtedy byś zrobił

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

auto myFoo = foo(55); 
+0

Być może miałeś na myśli: "szablon Foo foo (T x)"? –

2

w C++ 11 można użyć decltype:

int myint = 123; 
Foo<decltype(myint)> MyFoo(myint); 
Powiązane problemy