Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [C++] problemi di compilazione con std::list<T>::iterator

    Avendo codice come questo
    codice:
    template<class T>
     std::list<T>::iterator nomefunzione()
    {
       std::list<T> _list;
       //.. codice
       return _list.begin();
    }
    ottengo un errore dal compialtore (sto lavorando con visual studio 2012)
    warning C4346: 'std::list<T>::iterator': il nome dipendente non è un tipo
    Andando in giro a cercare su internet ho scoperto che per nona vere questo errore devo sempre premettere la keyword typename .
    Effettivamente riscrivendo la funzione come segue non ottengo errori:
    codice:
    template<class T>
     typename std::list<T>::iterator nomefunzione()
    {
       std::list<T> _list;
       //.. codice
       return _list.begin();
    }
    Francamente l'unica spiegazione che ho trovato mi risulta aimè molto ostica e non riesco realmente a comprenderla
    The point is that you have a template that uses another template based on its own template parameters. That means that if e.g. the other class is specialised for a certain type, it could change the whole interface when compared to the general template, including sometimes twisting around the meaning of things.
    Example: under weird circumstances, e.g. list<weird_thing>::iterator might
    in fact refer to a static member. Not that there is any reason to do just
    that with list<>, but it's not up to the compiler to reason. Therefore,
    when referring to a nested type or typedef, you need to prefix it
    with 'typename' in this context.
    Inoltre ho un altro problema:
    Nel file che sto scrivendo list::iterator appare in numerosi punti, avevo quindi pensato di usare una comoda typedef, come potrebbe essere questa
    codice:
    template<class T> typedef std::list<T>::iterator listIterator<T>;
    ovviamente non compila e da lo stesso problema di cui sopra.. in questo caso non posso però premettere la keyword typename : esistono altri metodi per ottenere lo stesso risultato?

  2. #2

    Re: [C++] problemi di compilazione con std::list<T>::iterator

    Originariamente inviato da MegaAlchimista
    Francamente l'unica spiegazione che ho trovato mi risulta aimè molto ostica e non riesco realmente a comprenderla
    Come spiegato qui, il punto è che la "compilazione" di un template avviene in due fasi: c'è una prima verifica sintattica "di base", quindi, nel momento in cui viene effettivamente istanziato (specificando un tipo), avviene la compilazione vera e propria.

    Ora, nella prima fase vengono verificati diversi aspetti sintattici fondamentali, senza però sapere ancora esattamente che tipo verrà passato come parametro template.
    In questo passaggio, tuttavia, qualunque espressione del tipo tipo<T>::qualcosa è sostanzialmente ambigua, dato che, anche se nella definizione di base di tipo<T> qualcosa è un typedef o in generale rappresenta un tipo, nulla impedisce che una specializzazione particolare della classe definisca qualcosa come, ad esempio, campo statico (al quale ci si riferisce con la medesima sintassi, ma ha ovviamente una semantica completamente diversa).
    Per questo motivo, lo standard impone che, durante questo primo passaggio, tutti gli identificatori del tipo tipo<T>::qualcosa vengano considerati a priori come un valore, e non come un tipo. Da questo il messaggio di errore: iterator è il "nome dipendente" (dall'effettiva definizione di std::list<T>) e non viene considerato come un tipo, ma come un valore.

    Per specificare al compilatore che invece il nome dipendente a cui ti riferisci è un tipo (e dunque è ammissibile usarlo come tipo restituito per la tua funzione) si usa la keyword typename, che forza l'interpretazione del nome dipendente come tipo.
    Inoltre ho un altro problema:
    Nel file che sto scrivendo list::iterator appare in numerosi punti, avevo quindi pensato di usare una comoda typedef, come potrebbe essere questa
    codice:
    template<class T> typedef std::list<T>::iterator listIterator<T>;
    ovviamente non compila e da lo stesso problema di cui sopra.. in questo caso non posso però premettere la keyword typename : esistono altri metodi per ottenere lo stesso risultato?
    Il problema è che non è possibile avere dei typedef con parametri template (o meglio, puoi avere un typedef all'interno di una classe template, ma non puoi avere un typedef "a sé stante" parametrizzato con un parametro template); tuttavia, in C++11 (l'ultima revisione dello standard) è possibile fare qualcosa del genere con la keyword using.
    http://en.wikipedia.org/wiki/C%2B%2B11#Alias_templates
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3

    Re: Re: [C++] problemi di compilazione con std::list<T>::iterator

    Originariamente inviato da MItaly
    [...]
    Il problema è che non è possibile avere dei typedef con parametri template (o meglio, puoi avere un typedef all'interno di una classe template, ma non puoi avere un typedef "a sé stante" parametrizzato con un parametro template); tuttavia, in C++11 (l'ultima revisione dello standard) è possibile fare qualcosa del genere con la keyword using.
    http://en.wikipedia.org/wiki/C%2B%2B11#Alias_templates
    Innanzitutto grazie per la risposta chiara ed esaustiva.
    Andiamo al problema della typedef.
    Premesso che il mio compilatore supporta lo standard C++11 e che già utilizzo alcune delle sue funzionalità (come le enum class o nullptr o i thread ...) , non riesco a "far funzionare" la keyword using.
    Il seguente è stato il mio approccio:
    -Utilizzando già thread, enum class e compagnia bella ho dato per scontato di avere accesso a tutte le funzionalità dell'ultimo standard.
    Sono partito prendendo direttamente l'esempio pratico di wikipedia
    codice:
    template <typename First, typename Second, int Third>
    class SomeType;
    
    template <typename Second>
    using TypedefName = SomeType<OtherType, Second, 5>;
    questo non va bene per il mio caso , infatti scrivendo semplicemente
    codice:
    template<typename T> using list_iterator = std::list<T>::iterator;
    //errore di sintassi 'using'
    Sul momento ho pensato che l'errore fosse legato a tutto ciò che abbiamo appena detto, ed ho provato semplicemente ad aggiungere typename
    codice:
    template<typename T> using list_iterator = typename std::list<T>::iterator;
    Niente da gli stessi errori anche così.

    Così ho fatto qualche ricerca e su StackOverFlow ho trovato questo
    codice:
    template <class A>
    struct Y
    {
      using Left = typename A::Left;
      using Right = typename A::Right;
      using AReverse = typename A::Sibling<Right, Left>; // Gives a compiler error
     };
    //dice che essendo Sibling un template bisogna scrivere in questo modo
    using AReverse = A::template Sibling<Right, Left>;
    Allora ho tentato di applicare questo concetto al mio caso , pensando potesse funzionare
    codice:
    template<typename T>
    using list_iterator = typename std::list<T>::iterator;
    // l'ho riscritto come:
    template<typename T>
    using list_iterator = std::list<T>::typename iterator;
    sempre gli stessi errori.. così mi è sorto un dubbio, ed ho provato a scrivere:
    codice:
    template<typename T> using lista = std::list<T>;
    //error C2988: dichiarazione/definizione di modello non riconoscibile
    //error C2059: errore di sintassi: 'using'
    Finalmente ho ben pensato di leggere quali fossero gli errori:
    "dichiarazione di modello non riconoscibile"? Non è che non supporta lo standard?
    Infatti non compila nemmeno il caso più semplice di tutti
    codice:
    using listaIntera = std::list<int>;
    qui però da errori diversi
    Errore 1 error C2143: errore di sintassi: ';' mancante prima di '='
    Errore 2 error C2873: 'listaIntera': il simbolo non può essere utilizzato in una dichiarazione using
    Errore 3 error C2513: 'int': nessuna variabile dichiarata prima di '='
    ho come l'impressione che non supporti C++11, eppure questo mi sembra impossibile dato che (come già detto) uso tante altre "novità" introdotte nello standard.

    Oppure (probabile) non ho capito niente sul suo utilizzo

  4. #4
    Risolto l'arcano: non è supportato in visual studio come scritto sulla documentazione msdn andando a vedere la voce Alias Templates .

    (Questa cosa devo dire che mi infastidisce alquanto)

  5. #5
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Herb Sutter ha annunciato che verso aprile sarà distribuito un aggiornamento del compilatore (presumo un service pack) per allineare il compilatore e relativa libreria al pieno supporto C++11.
    Nel frattempo è stato distribuito un aggiornamento di test (il VC++ CTP) che supporta una parte della uniform initialization sintax e i variadic template. Tuttavia è solo il compilatore che supporta le nuove features, per la libreria dovremo aspetta ancora un po'.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.