2015-12-28 12 views
6

Podczas nauki i eksperymentowania z szablonami natknąłem się na coś, czego nie mogłem w pełni zrozumieć.W jaki sposób argumenty szablonów są rozwiązywane/wydedukowane?

class sample 
{ 
    public: 
     sample(int a = 0) {} 
}; 

template <typename T1,typename T2> 
void add(T1 a) // Replace T1 with T2 resolves compilation error. 
{} 

int main() 
{ 
    add<sample>(3); 
    return 0; 
} 

Powyższy kod powoduje błąd kompilacji (zarówno 03, jak i 0x 0x). Ale kiedy zmieniam typ argumentu dodawania z T1 na T2, jest w porządku. Przy nm, utworzony prototyp to add (sample, int) [T1 = sample, T2 = int]. Dlaczego kompilacja kończy się niepowodzeniem z T1 jako typem argumentu, ale nie T2?

Odpowiedz

6

Istnieją dwa sposoby określenia argumentów szablonu: jawnie lub niejawnie.

Byłoby to jednoznaczne:

template<typename T> 
void do_something(T value) {}; 

do_something<float>(6); // T is float 

Byłoby niejawna:

int x; 

do_something(x); // since first argument is T and x is int, T is int 

W twoim przypadku:

template <typename T1,typename T2> void add(T1 a); 
add<sample>(3); // T1 is explcitly sample, T2 is unknown 

Przypadek 2:

template <typename T1,typename T2> void add(T2 a); 
add<sample>(3); // T1 is explcitly sample, T2 is implicitly int 
1

Dzieje się tak, ponieważ klasa sample może zostać niejawnie utworzona z int. I tak, gdy podasz <sample> jako argument typu, int dopasowuje pierwszy parametr typu <sample>, niejawnie, ale T2 jest niezdefiniowany, ponieważ nie można go wywnioskować na dowolny typ.

Nie zdarza się to w drugim przypadku, bo wtedy można określić częściowo typy: <sample> określa typ T1, i int można następnie wyprowadzić na T2, a wszystkie rodzaje szablonów są wywnioskować. Nawet jeśli wszystkie typy nie są używane, jest to w porządku.

Powiązane problemy