2009-08-19 15 views
5

scrivendo una funzione template, ho dichiarato:g ++ "non è un tipo di" errore

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

compilazione con g ++ 4.0.1 ho ottenuto l'errore:

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

risposta

7

Come hai scoperto, T :: size_type deve essere preceduto da typename. Perché?

Da "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

Ora ho letto quel passaggio, grazie (quelli che leggono a casa possono vedere la spiegazione dettagliata a pagina 130). Non vedo ancora perché "typename" sia richiesto in una dichiarazione di argomento, in quanto deve essere un tipo, ma forse è solo per coerenza con le affermazioni in generale. –

+1

@wnissen: in genere tali requisiti esistono per mantenere i parser builder felici. Parte del problema è che a quanto pare già sai che è una dichiarazione di argomento. A causa del problema "parsing più fastidioso", il parser in genere deve dedurre quello dai token tra(). Ora, se dici che l'interpretazione dei token tra() dovrebbe dipendere dal sapere che è una dichiarazione di argomento, allora hai introdotto un problema di analisi ciclica. – MSalters

29

È necessario aggiungere typename.

I.e.

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

Senza avere alcuna informazione sul tipo T, il compilatore ha bisogno di sapere che T :: size_type designa un tipo.

dalla norma, sezione 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

Si è scoperto che avevo bisogno di specificare che T :: size_type era un typename. Perché?

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

di disambiguare tra un possibile nome dell'istanza e un possibile nome di tipo. Per maggiori informazioni leggi il libro C++ Templates; La guida completa - informazioni su http://www.josuttis.com/tmplbook/tmplbook.html –

+1

che dovrebbe essere una domanda separata. (Anche se è stato chiesto prima. Cerca un po ') – jalf

3

Perché durante l'analisi della dichiarazione del modello, T non è noto. Quindi il compilatore non sa se esiste T :: size_type. Può riferirsi ad una variabile statica, per esempio. Quando in seguito utilizzi il modello, T è ovviamente noto, ma l'errore si verifica prima. E per favore usa qualcosa di meno antico di gcc 4.0.1 ;-)

Modifica: Se lo compili con -fpermissive, il compilatore probabilmente mastica il tuo codice, ma darà un avvertimento.

+0

gcc 4.0.1 è il più recente - sul mac :) – Tobias

+1

Se vero, ancora un altro motivo per non utilizzare un mac. L'ultima qualità di produzione g ++ è 4.4.0 –

+0

In realtà gcc 4.4.1. – hirschhornsalz

Problemi correlati