2009-08-19 28 views
5

Pisanie szablonie funkcji, oświadczyłem:g ++ "nie jest typu" błąd

template <typename T> 
T invertible(T const& container, T::size_type startIndex, T::size_type endIndex); 

Kompilacja z g ++ 4.0.1 mam błąd:

error: 'T::size_type' is not a type 

Odpowiedz

7

Jak się dowiedziałeś, T :: size_type musi mieć prefiks z typename. Dlaczego?

Od "C++ Templates: The Complete Guide"

The language definition resolves this problem by specifying that in general a dependent qualified name does not denote a type unless that name is prefixed with the keyword typename.

... The typename prefix to a name is required when the name

  1. Appears in a template
  2. Is qualified
  3. Is not used as a list of base class specifications or in a list of member initializations introducing a constructor definition
  4. Is dependent on a template parameter

Furthermore the typename prefix is not allowed unless at least the first three previous conditions hold.

+0

Przeczytałem już ten fragment, dzięki (osoby czytające w domu mogą zobaczyć szczegółowe wyjaśnienie na stronie 130). Nadal nie rozumiem, dlaczego "typename" jest wymagana w deklaracji argumentu, ponieważ musi to być typ, ale może to tylko dla spójności z instrukcjami w ogóle. –

+1

@wnissen: Zazwyczaj takie wymagania istnieją, aby budowniczowie parserów byli zadowoleni. Częścią problemu jest to, że najwyraźniej już wiesz, że to deklaracja argumentacyjna. Ze względu na problem "najbardziej irytujący parse" parser zwykle musi wydedukować to z tokenów pomiędzy(). Teraz, jeśli powiesz, że interpretacja tokenów pomiędzy() powinna zależeć od tego, czy wiesz, że jest to deklaracja argumentu, to wprowadziłeś cykliczny problem z analizą. – MSalters

29

Trzeba dodać TypeName.

tj.

template <typename T> 
T invertible(T const& container, typename T::size_type startIndex, typename T::size_type endIndex); 

Bez żadnych informacji na temat typu T kompilator musi wiedzieć, że T :: size_type oznacza typ.

od standardu, rozdział 14.6.2:

A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename .

0

Okazało się, że muszę podać, że T :: size_type był typename. Dlaczego?

template <typename T> 
T invertible(T const& container, typename T::size_type startIndex, typename T::size_type endIndex); 
+0

disambiguate między ewentualnej nazwy instancji i ewentualnej nazwy typu. Aby uzyskać więcej informacji przeczytaj książkę C++ Templates; Kompletny przewodnik - informacje na http://www.josuttis.com/tmplbook/tmplbook.html –

+1

, które powinny być osobnym pytaniem. (Mimo, że zapytano go wcześniej.) Poszukaj trochę) – jalf

3

Ponieważ podczas parsowania deklaracji szablonu, T nie jest znane. Tak więc kompilator nie wie, czy T :: size_type istnieje w ogóle. Może na przykład odnosić się do zmiennej statycznej. Gdy później użyjesz szablonu, T jest oczywiście znane, ale błąd występuje wcześniej. I proszę użyj czegoś mniej starożytnego niż gcc 4.0.1 ;-)

Edycja: Jeśli skompilujesz go z -fpermissive, prawdopodobnie kompiluje twój kod, ale ostrzeże go.

+0

gcc 4.0.1 jest najbardziej aktualnym - na Macu :) – Tobias

+1

Jeśli to prawda, to kolejny powód, dla którego nie używasz mac. Najnowsza jakość produkcji g ++ wynosi 4.4.0 –

+0

Właściwie gcc 4.4.1. – hirschhornsalz

Powiązane problemy