2011-07-23 6 views
9

Deklarowanie znajomych funkcji szablonów wymaga niewiarygodnie nieintuicyjnej składni, nawet w C++! Jakie jest uzasadnienie wyboru składni dla potrzebnej dodatkowej <>? Czy nie byłoby lepiej używać słowa kluczowego template?Jakie są przesłanki dotyczące składni wybranej do deklarowania znajomych z szablonu?

Dla tych, którzy nie wiedzą o tym, tutaj jest przykładem tego, co można spróbować zrobić:

template <typename T> 
class Foo 
{ 
    int x; 
    friend void bar(Foo<T>); 
}; 

template <typename T> 
void bar(Foo<T> f) 
{ 
    std::cout << f.x; 
} 

Jeśli spróbujesz zadzwonić bar(Foo<T>()), dostaniesz błędy linkera.

Aby rozwiązać ten problem, należy przesłać dalej deklarację bar (a tym samym Foo), a następnie umieścić dziwnie umieszczone <> w deklaracji przyjaciela.

template <typename T> class Foo; 
template <typename T> void bar(Foo<T>); 

template <typename T> 
class Foo 
{ 
    int x; 
    friend void bar<>(Foo<T>); // note the <> (!?) 
}; 

template <typename T> 
void bar(Foo<T> f) 
{ 
    std::cout << f.x; 
} 

Moje pytanie brzmi, jakie jest uzasadnienie składni <>? Czy nie byłoby bardziej intuicyjnie używać słowa kluczowego template lub czegoś podobnego?

EDIT: Do wyjaśnienia, już wiem dlaczego <> jest wymagane, co chcę wiedzieć, dlaczego zdecydowali się użyć <> disambiguate go zamiast innego bardziej intuicyjnej składni.

+1

+1 Zastanawiałem to dla długi czas. Na tym polega dyskusja w "Effective C++", ale nie całkiem to rozumiem. – templatetypedef

+1

Mam nadzieję, że ta nieintuicyjna rzecz stanie się intuicyjna w C++ 11 –

+1

@Hades: O ile nie przeoczyłem tego, nic się nie zmieniło pod tym względem dla C++ 11. –

Odpowiedz

2

Cytowanie this page:

Funkcja non-szablon nazywa, ponieważ funkcja nie szablon ma pierwszeństwo w rozdzielczości przeciążenia.

Więc moja Odgadnij friend void bar<>(Foo<T>); jest intuicyjna, ponieważ chcemy, aby upewnić się, że funkcja szablon dzwonisz i nie przeciążenia dla Foo<T>. W przeciwnym razie kompilator nie zauważyłby, czy szablonowa lub niesformowana funkcja jest przyjacielem klasy.

Dlaczego składnia <> jest używana, a nie składnia template nie jest dla mnie jasna.

+0

Dzięki, ale jest to część dotycząca '<>' vs.'szablon', który chcę poznać :-) –

+0

@Peter Alexander: Ah, ale zostawię moją odpowiedź na teraz, to może zainspirować kogoś bardziej kompetentnego niż ja w C++ do prawdziwej odpowiedzi. – orlp

6

Czekaj. Nie deklarujesz szablonu znajomego. Deklarujesz specjalizację szablonu jako przyjaciela! W związku z tym, dlaczego chcesz umieścić tam klauzulę template?

Składnia nazw specjalności szablonów funkcji to teplateName<ArgumentList>, i to jest to, czego należy użyć zgodnie ze Standardem w deklaracjach przyjaciół.

Jeśli chcesz się zaprzyjaźnić cały szablon i wszystkie specjalizacje generowane i wyraźnie wyspecjalizowane, można jeszcze zrobić, a potem może użyć klauzuli szablonu

template<typename U> 
friend void bar(Foo<U>); 
+0

Jeśli składnia jest oparta na specjalizacji, dlaczego nie ma składni: "template <> friend void bar (Foo );'? Dlaczego umieszczam pustą listę parametrów szablonu bez słowa kluczowego szablonu? –

+0

@Peter dobrze, 'szablon <> przyjaciel void bar (Foo );' wygląda mi na wyraźną specjalizację ('szablon <>' służy tylko do deklarowania wyraźnych specjalizacji). Ale deklaracja znajomego, którą napisałeś w swoim pytaniu, nie wymaga istnienia wyraźnej specjalizacji szablonu. Zaprzyjaźnia się także z instancjami szablonu. Mogę sobie wyobrazić, że było to uzasadnienie dla niewykorzystywania 'szablonu <>" - ludzie mogą wprowadzać w błąd, sądząc, że zadeklarują wyraźną specjalizację. –

+0

@Peter być może powinienem wyjaśnić, kiedy mówię "Deklarujesz specjalizację szablonu jako przyjaciela", używam terminu, który Standard definiuje "specjalizacja". Nie to, za co większość programistów C++ go używa. Są generowane specjalizacje, które kompilator tworzy dla ciebie, tworząc instancję szablonu. Istnieją wyraźne specjalizacje, które programista tworzy i gdzie nie ma potrzeby tworzenia instancji. Moje użycie tego terminu nie określało żadnego z tych dwóch rodzajów. Użycie 'szablonu <> w deklaracji wprowadza wyraźną specjalizację. –

Powiązane problemy