Toon posts:

[C++] Typedef vector in template class

Pagina: 1
Acties:

Verwijderd

Topicstarter
Het volgende probeert men hier op mijn werk te doen (en ik mag het porten :( ):

C++:
1
2
3
4
5
template <class T>
class NNSearch {
public:
    typedef typename std::vector<T> SDVector_Type;
};


Mag dit?

GCC schijnt er geen problemen er mee te hebben, en ook van Intel C++ 7 mag het.
De HPUX compiler (aCC) geeft een error:

line 17 # 'vector<#1,std::allocator>' is used as a type, but has not been defined as a
type.

Terwijl de Itanium Compiler ook van HP het wel doorlaat maar ergens verder een hele rare error geeft, wat waarschijnelijk hier mee te maken heeft.
Enig idee?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:16

.oisyn

Moderator Devschuur®

Demotivational Speaker

Die typename mag je weglaten, maar dat hoeft niet. Heb je <vector> wel geinclude?

Wanneer krijg je de error? Bij de definitie van die template class, of het instantieren ervan?

[ Voor 30% gewijzigd door .oisyn op 06-01-2004 18:10 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
.oisyn schreef op 06 januari 2004 @ 18:09:
Die typename mag je weglaten, maar dat hoeft niet. Heb je <vector> wel geinclude?
Als ik de typename weglaat dan schijnt hij er door heen te komen. Ik kreeg wel een error:

C++:
1
std::list<SDVector_Type>::iterator it;


maar die mist daar gewoon een typename...

Wat zegt precies de C++ standaard hier over, is de typename bij die typedef toelaatbaar of mag het gewoon niet?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:16

.oisyn

Moderator Devschuur®

Demotivational Speaker

Maar bij die definitie van it moet wel typename staan ;)

Het zit 'm in het verschil tussen het parsen van een template class of functie, en het instantieren ervan. Tijdens het parsen moet namelijk bekend zijn wat een type is en wat niet. Aangezien het een template is, kan het pas later duidelijk worden wat het nou is, en moet je de compiler dus af en toe een hint geven.

Bij je eerste stukje code hoeft dat niet. std::vector is al bekend, en dat is gewoon een class, dus een type.

Bij de std::list<SDVector_Type>::iterator is het een ander verhaal. std::list is een type, dat is al bekend. Maar het gaat hier om de iterator. Dat kan een type of een iets anders zijn, afhankelijk van de definitie van SDVector_Type. Dat is namelijk omdat je een template kunt specializen. Je kunt bijvoorbeeld een list maken die bij T=void een iterator heeft wat een int is, en bij T=char een iterator wat een functie is. En dat weet je dus pas op het moment van instantiatie, dus echt het gebruik van je template class/functie. In die gevallen moet je de compiler een hint geven, en dus moet je

C++:
1
typename std::list<SDVector_Type>::iterator it;


doen


Verder mag het typename keyword alleen gebruikt worden in templates, maar volgens mij is het niet verboden om 'm in die templates te gebruiken op plaatsen waar het eigenlijk niet hoeft, zoals in je eerste stukje code. Comeau klaagt er iig niet over.
Buiten templates is het iig wel verboden

[ Voor 15% gewijzigd door .oisyn op 06-01-2004 18:41 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
.oisyn schreef op 06 januari 2004 @ 18:37:
Maar bij die definitie van it moet wel typename staan ;)

Het zit 'm in het verschil tussen het parsen van een template class of functie, en het instantieren ervan. Tijdens het parsen moet namelijk bekend zijn wat een type is en wat niet. Aangezien het een template is, kan het pas later duidelijk worden wat het nou is, en moet je de compiler dus af en toe een hint geven.

Bij je eerste stukje code hoeft dat niet. std::vector is al bekend, en dat is gewoon een class, dus een type.

Bij de std::list<SDVector_Type>::iterator is het een ander verhaal. std::list is een type, dat is al bekend. Maar het gaat hier om de iterator. Dat kan een type of een iets anders zijn, afhankelijk van de definitie van SDVector_Type. Dat is namelijk omdat je een template kunt specializen. Je kunt bijvoorbeeld een list maken die bij T=void een iterator heeft wat een int is, en bij T=char een iterator wat een functie is. En dat weet je dus pas op het moment van instantiatie, dus echt het gebruik van je template class/functie. In die gevallen moet je de compiler een hint geven, en dus moet je

C++:
1
typename std::list<SDVector_Type>::iterator it;


doen


Verder mag het typename keyword alleen gebruikt worden in templates, maar volgens mij is het niet verboden om 'm in die templates te gebruiken op plaatsen waar het eigenlijk niet hoeft, zoals in je eerste stukje code. Comeau klaagt er iig niet over.
Buiten templates is het iig wel verboden
Bedankt voor de info. In elk geval aCC op de HP-Itanium struikelt er over en zal een error geven en op de HP-UX zal ook een error geven. Al zijn beide errors wel op andere plaatsen.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
typename is nu iets wat alleen mag waar het ook moet. Dat gaat veranderen, maar we zijn een jaar of zo verder voordat compilers dat snappen ('t is niet heel moeilijk voor compiles om iets te negeren. )

typename moet gebruikt woren op dependent types. Dat wil zoveel zeggen, op identifiers die voor sommige definities van de template parameter(s) geen type hoeven te zijn. Als de template parameter T is, dan is T::X dus dependent. Er kan een T zijn waarin T::X geen type maar een data member is, of een functie.

std::vector<T> is altijd een type, omdat de concrete T geen invloed heeft op std::vector< >. Alle specialisaties van een class template zijn zelf ook class templates.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 123% gewijzigd door Eelis op 18-02-2015 19:53 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Er zijn twee vormen van specialisaties; 14.5.4.1 partiele specialisaties en 14.7/3, volledige specialisaties. vector<bool> is een geval van de laatste. De declaratie zelf ( het statement dat begint met template< > vector<bool> {... ) is noch een template, noch een class, maar een specialisatie van een bestaand template.

14.5.4/3 is anders:
Each class template partial specialization is a distinct template
Het maakt alleen niet zoveel uit hier. Mijn eerste poging rammelde wat. De template parameter T zelf is al dependent, en het moge duidelijk zijn dat je niet overal typename T hoeft te schrijven. typename is pas nodig waar een dependent type als qualifier wordt gebruikt.

Het complete standaard verhaal gaat als volgt:
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.
We zoeken hier 3 namen, std, vector en T. std wordt via een unqualified lookup gevonden als namespace name, daarna wordt volgens 3.4.3.2/1 vector als template-id gevonden en de class T wordt gevonden in de locale (template) scope. De enige naam die een type aanduidt is dus T; std is een namespace naam en vector een template naam.
Deze lookup gebeurt tijdens instantiatie, niet compilatie (14.6.2/2).

Het geheel ( std::vector<T> ) is dus wel een type, maar 3 namen en typename wordt gebruikt om van een enkele onduidelijke naam aan te geven dat het een type is.

De volgende vraag is of het fout is. Zoals ik het lees is het fout, omdat je std::vector ermee prefixt. vector is geen type, maar een template.
Hier geldt 14.6.2/3
A qualified-id that refers to a type and in which the nested-name-specifier depends on a template-parameter (14.6.2) shall be prefixed by the keyword typename to indicate that the qualified-id denotes a type...
Dit maakt het helemaal duidelijk. nested-name-specifier specifier is het deel voor de laatste ::, dus in A::B<C>::D is dat alles behalve D. In ons geval is het alleen std::, en dat hangt overduidelijk niet van T af.

.modbreak: Je was ergens een [/quote] vergeten waardoor het verkeerd ging en er ergens een lap tekst weg viel (een quote in een quote resulteert in een "[..]"). Ik heb het even geedit :)

[ Voor 10% gewijzigd door .oisyn op 11-01-2004 21:54 ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1