2009-08-12 22 views
21

Stworzyłem dwie proste funkcje, które ulegną parametry szablonu i pusty struct określającą typ:Dlaczego odliczanie argumentu szablonu nie działa tutaj?

//S<T>::type results in T& 
template <class T> 
struct S 
{ 
    typedef typename T& type; 
}; 

//Example 1: get one parameter by reference and return it by value 
template <class A> 
A 
temp(typename S<A>::type a1) 
{ 
    return a1; 
} 

//Example 2: get two parameters by reference, perform the sum and return it 
template <class A, class B> 
B 
temp2(typename S<A>::type a1, B a2)//typename struct S<B>::type a2) 
{ 
    return a1 + a2; 
} 

Argument type jest zastosowane do struct S uzyskać odniesienie. Nazywam je z pewnymi wartościami całkowitymi ale kompilator nie jest w stanie wydedukować argumenty:

int main() 
{ 
    char c=6; 
    int d=7; 
    int res = temp(c); 
    int res2 = temp2(d,7); 
} 

Error 1 error C2783: 'a temp (S :: type)': nie można wywnioskować argument szablonu 'A'

błąd 2 error C2783: 'B temp2 (S :: typ B)': nie mógł wywieść szablon argumentem dla 'A'


Dlaczego tak się dzieje? Czy trudno jest zauważyć, że argumenty szablonu są wartościami 01?

Odpowiedz

27

Tak jak w pierwszej notatce, nazwa nazwy pliku jest używana, gdy wspomniano o nazwie zależnej od nazwy. Więc nie potrzebujesz tego tutaj.


template <class T> 
struct S 
{ 
    typedef T& type; 
}; 

odniesieniu do konkretyzacji szablonu, problemem jest to, że typename S<A>::type charakteryzuje nondeduced kontekst A. Gdy parametr szablon jest używany tylko w nondeduced kontekście (miejsce w przypadku w swoich funkcji) nie jest brana pod rozważenie odliczenia argumentów szablonu. Szczegóły podano w sekcji 14.8.2.4 normy C++ (2003).

Aby kontynuować pracę połączenia, trzeba jednoznacznie określić typ:


temp<char>(c); 
+2

witamy w SO. i +1 :) –

+0

Edytowałem cytat przez jakiś czas. Po pierwsze, więc +1 :) –

6

To wygląda nondeduced kontekście. Według C++ standard 14.8.2.4/4:

W nondeduced konteksty są:

  • nested-name-specifier typu, który został określony za pomocą kwalifikowaną id.
  • typu, który jest szablon ID w których jeden lub więcej z od matrycy, argumentów jest wyrażeniem odwołuje szablonu parametr.

Gdy nazwa typu jest określona w sposób obejmujący nieprzestrzegany kontekst, wszystkie typy zawierające nazwę tego typu również nie są pomijane. Jednakże, typ złożony może obejmować typy zarówno wydedukowane, jak i niepodane. [] Przykład: Jeśli typ jest określony jako A<T>::B<T2>, zarówno T, jak i są niepowiązane. Podobnie, jeśli typ jest określony jako A<I+J>::X<T>, I, J i T są niepodejmowane.Jeśli typ jest określony jako void f(typename A<T>::B, A<T>), to nie jest on leczony, ale wydedukowano T w . ] Działa

+0

Czy możesz wyjaśnić mi to prostymi słowami za pomocą przykładów: 'Specyfikator nazwy zagnieżdżonej typu, który został określony przy użyciu kwalifikowanego-id. Wiem, że specyfikator nazw zagnieżdżonych to' X :: 'i kwalifikowany id to taki, który ma przedrostek' :: ', ale nie może dojść do porozumienia lub zrozumieć całego problemu. Wielkie dzięki :) –

+0

jest jak '(** Specyfikator typu zagnieżdżonego typu **), który został określony przy użyciu kwalifikowanego identyfikatora. 'lub' Specyfikator nazwy zagnieżdżonej (typ **, który został określony przy użyciu kwalifikowanego identyfikatora. **) ' –

4

Potrącenie w kierunku do przodu:

template <class T> void f(T); 

f(2); // can deduce int from T 

Dlaczego tak się dzieje?

To nie działa w kierunku wstecznym (Twój przykład):

template <class A> void g(typename S<A>::type); 

się, że trudno zauważyć, że argumenty szablonu są char i int wartości?

Odliczanie szablonów może zrobić pewne magiczne rzeczy (Turing-complete), ale nie sądzę, że jest to jedna z nich.

Możecie użyć czegoś podobnego (niesprawdzone):

template <class SA> void h(SA a1) 
{ 
    STATIC_ASSERT(same_type<SA, S<A>::type>::value); 
    typedef typename SA::type A; 

    ... 
} 

Korzystanie swoją ulubioną bibliotekę statyczną assert (doładowania ma dwa).

+0

A teraz także w STL: http://en.cppreference.com/w/cpp/ language/static_assert – ibizaman

Powiązane problemy