[C++] Probleem met templates

Pagina: 1
Acties:

  • c0deaddict
  • Registratie: Mei 2004
  • Laatst online: 10-01 12:11

c0deaddict

Don't be lame, be KLEI

Topicstarter
Hallo,

Ik was gisteren wat aan't prutz0ren met templates in de voor mij nieuwe taal C++.
Na veel turorials gelezen te hebben ben ik begonnen met het maken van een dynamische lijst (wat in STL "vector" heet).
Ik heb dus eerst een basis klasse geschreven om te kijken of mijn gedachte over templates klopte:

list.h
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef __LIST_H__
#define __LIST_H__

template <class T> class List 
{
public:
  List();
  ~List();

  void blaat();
};

#endif /* __LIST_H__ */


list.cpp
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <list.h>
#include <messages.h>

template class <T> 
List<T>::List()
{
  // constructor
}

template class <T> 
List<T>::~List()
{
  // destructor
}

template class <T> 
void List<T>::blaat()
{
  info("blaat\n");
}


main.cpp
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <list.h>
#include <messages.h>

int main(int argc, char **argv)
{
  List<int> bla;

  init_message_system();

  bla.blaat();

  destroy_message_system();
}


Maar als ik het geheel nu compileer onder Visual Studio 6 dan krijg ik errors bij het linken:
code:
1
main.obj : error LNK2001: unresolved external symbol "public: __thiscall List<int>::List<int> (void) .....


Ik snap niet hoe dit komt, want als ik de methoden in list.h definieer (zie onder) dan werkt alles wel :?
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef __LIST_H__
#define __LIST_H__

template <class T> class List 
{
public:
  List();
  ~List();

  void blaat();
};

template class <T> 
List<T>::List()
{
  // constructor
}

template class <T> 
List<T>::~List()
{
  // destructor
}

template class <T> 
void List<T>::blaat()
{
  info("blaat\n");
}

#endif /* __LIST_H__ */


Heeft iemand enig idee wat ik fout doe ?

Alvast Bedankt ! :)

offtopic:
C++ is nieuw voor mij, maar C ken ik wel :)

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

.oisyn

Moderator Devschuur®

Demotivational Speaker

[nohtml]Je moet je template definieren als export, maar er zijn maar weinig compilerimplementaties die dat ondersteunen. Het andere alternatief is om de implementatie ook in de header te plaatsen, of in een andere file die je include vanuit de header.

Omdat de compiler nog niet weet met welke types je template geinstantieerd wordt kan hij ook nog geen code genereren. Aangezien jij de implementatie niet duidelijk maakt als main.cpp gecompileerd wordt, gaat de compiler ervanuit dat de code uit een andere sourcefile gegenereerd wordt. Alleen als de linker alle gecompileerde files bij elkaar gaat voegen blijkt de implementatie van List te missen. Die kan niet in List.cpp staan, aangezien de compiler tijdens het compileren van List.cpp niet kan weten dat de lijst ooit met een int geinstantieerd wordt. Een export lost dit op, dit stelt de compilatie namelijk uit tot link-time, maar zoals gezegd zijn er maar weinig compilers die het ondersteunen.

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

KLEI_j0s schreef op maandag 17 januari 2005 @ 14:59:
C++:
1
2
3
4
5
template class <T> 
List<T>::List()
{
  // constructor
}
Die syntax klopt niet (template <class T> is wel goed), ik vraag me af waarom je compiler niet gaat gillen?.

  • c0deaddict
  • Registratie: Mei 2004
  • Laatst online: 10-01 12:11

c0deaddict

Don't be lame, be KLEI

Topicstarter
.oisyn schreef op maandag 17 januari 2005 @ 15:05:
[nohtml]Je moet je template definieren als export, maar er zijn maar weinig compilerimplementaties die dat ondersteunen. Het andere alternatief is om de implementatie ook in de header te plaatsen, of in een andere file die je include vanuit de header.

Omdat de compiler nog niet weet met welke types je template geinstantieerd wordt kan hij ook nog geen code genereren. Aangezien jij de implementatie niet duidelijk maakt als main.cpp gecompileerd wordt, gaat de compiler ervanuit dat de code uit een andere sourcefile gegenereerd wordt. Alleen als de linker alle gecompileerde files bij elkaar gaat voegen blijkt de implementatie van List<int> te missen. Die kan niet in List.cpp staan, aangezien de compiler tijdens het compileren van List.cpp niet kan weten dat de lijst ooit met een int geinstantieerd wordt. Een export lost dit op, dit stelt de compilatie namelijk uit tot link-time, maar zoals gezegd zijn er maar weinig compilers die het ondersteunen.
Aha, ik snap het :)
naja, dan moet alles maar in de header :p

iig bedank :D

  • c0deaddict
  • Registratie: Mei 2004
  • Laatst online: 10-01 12:11

c0deaddict

Don't be lame, be KLEI

Topicstarter
Verwijderd schreef op maandag 17 januari 2005 @ 15:06:
[...]


Die syntax klopt niet (template <class T> is wel goed), ik vraag me af waarom je compiler niet gaat gillen?.
Syntax klopt niet :?
waar dan :p

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

.oisyn

Moderator Devschuur®

Demotivational Speaker

C++:
1
2
3
4
5
template class <T>  
List<T>::List() 
{ 
  // constructor 
} 
Je "template class <T>" moet "template <class T>" zijn

[ Voor 30% gewijzigd door .oisyn op 17-01-2005 15:22 ]

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.


  • c0deaddict
  • Registratie: Mei 2004
  • Laatst online: 10-01 12:11

c0deaddict

Don't be lame, be KLEI

Topicstarter
.oisyn schreef op maandag 17 januari 2005 @ 15:21:
[...]


Je "template class <T>" moet "template <class T>" zijn
:X typo :p

Compiler zeurde niet omdat de source al wat uitgebreider was, en ik voor de ts ff een stukje overgetypt had...

[ Voor 9% gewijzigd door c0deaddict op 17-01-2005 15:34 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Je kan ook nog wat types expliciet instantieren in source files, als je van te voren weet wat er gebruikt gaat worden. Je kan bv al je templates voor double en float instantieren. Maar bij een list oid is dat lastig, dus dan in je header...l

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Als je met templates en de STL gaat werken, dan is VC6 geen goed idee. Te buggy.

Ten tweede mag jij geen identifiers met _[A-Z_] beginnen. De standaard header <list> mag de naam __LIST_H__ zelf gebruiken.

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


  • c0deaddict
  • Registratie: Mei 2004
  • Laatst online: 10-01 12:11

c0deaddict

Don't be lame, be KLEI

Topicstarter
MSalters schreef op maandag 17 januari 2005 @ 16:14:
Als je met templates en de STL gaat werken, dan is VC6 geen goed idee. Te buggy.

Ten tweede mag jij geen identifiers met _[A-Z_] beginnen. De standaard header <list> mag de naam __LIST_H__ zelf gebruiken.
Het enige waarvoor ik templates gebruik is List, single linked list en double linked list.
Helaas heb ik alleen maar VC6 dus geen keus :p
En STL gebruik ik niet ik heb zelf de nodige routines geschreven
Pagina: 1