2009-04-28 5 views
27

Czasami to czasami nie działa:Kiedy kompilator może wywnioskować parametr szablonu?

template <class T> 
void f(T t) {} 

template <class T> 
class MyClass { 
public: 
    MyClass(T t) {} 
}; 

void test() { 
    f<int>(5); 
    MyClass<int> mc(5); 
    f(5); 
    MyClass mc(5); // this doesn't work 
} 

Czy istnieje sposób, aby włamać się wokół powyższym przykładzie? To znaczy. zmusić kompilator do wyprowadzenia parametru szablonu z parametru konstruktora.

Czy zostanie to naprawione w przyszłości, czy też jest ku temu dobry powód?

Jaka jest ogólna zasada, gdy kompilator może odczytać parametr szablonu?

Odpowiedz

47

parametry szablonu można wywnioskować na szablonów funkcyjnych gdy typ parametru można wywnioskować z szablonu Parametry

Więc można wywnioskować tutaj:

template <typename T> 
void f(T t); 

template <typename T> 
void f(std::vector<T> v); 

ale nie tutaj:

template <typename T> 
T f() { 
    return T(); 
} 

I nie w szablonach klas.

Więc zwykle rozwiązanie problemu jest stworzenie funkcji otoki, podobną do funkcji standardowej biblioteki std::make_pair:

template <class T> 
    class MyClass { 
    public: 
     MyClass(T t) {} 
     void print(){ 
      std::cout<<"try MyClass"<<std::endl; 
     } 
    }; 

    template <typename T> 
    MyClass<T> MakeMyClass(T t) { return MyClass<T>(t); } 

a następnie zadzwonić auto a = MakeMyClass(5); instancji klasy.

+0

+1, dokładne. Minor nit: Proponuję zmienić "kiedy typ parametru jest zależny" na "kiedy typ parametru jest zależny". –

+2

void f (nazwa_typu T :: const_iterator t); << tutaj, T pojawia się w kontekście niezwiązanym. nawet, jeśli wywołujemy go za pomocą wektora :: const_iterator, na przykład nie będzie w stanie wydedukować wektora dla T. powodem jest to, że znaczenie :: const_iterator zależy od T., ale T znowu zależy od znaczenia :: const_iterator. dlatego boost :: implicit_cast jest kodowany w następujący sposób: template T implicit_cast (tożsamość typu nazwa :: type t) {return t; } znowu mamy kontekst niezwyciężony. –

+0

Standardowym refem jest 14.8.2.4/4 (najnowszy szkic C++ 1x ma adres 14.9.2.5/5 - ustalający również niektóre niedociągnięcia sformułowania w obecnym standardzie). :) Pozdrawiam –