Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[C++] Template defenition in header?

Pagina: 1
Acties:

  • maleadt
  • Registratie: Januari 2006
  • Laatst online: 05-11 22:08
Beste tweakers,

Bij het leren van C++ ben ik vandaag in contact gekomen met templates (met als doel, een zo generiek mogelijke stringify functie).

Ik ben dus begonnen met een algemene stringify, gebaseerd op templates, om die dan later uit te breiden voor specifieke gevallen (vb bij booleans, "true" & "false" in plaats van 1 en 0). De basiscode die in mijn .cpp komt is dus als volgt:
C++:
1
2
3
4
5
6
template<typename T> string stringify( const T& inputVariable )
{
    std::ostringstream tempStream;
    tempStream << inputVariable;
    return tempStream.str();
}


Maar omdat deze code in een aparte file komt, moet ik ook een defenitie ervan in mijn header plaatsen. Daar ondervind ik echter problemen, wat ik ook probeer, de linker vind geen referenties naar het gebruik van stringify... De huidige code die ik in mijn header heb:
C++:
1
template<typename T> string stringify(const T& inputVariable);


De stringify functie gebruik ik in server.cpp als volgt:
C++:
1
2
3
string clientAddress = inet_ntoa(clientData.sin_addr);
int clientPort = ntohs(clientData.sin_port);
outputInfo("Client " + clientAddress + " has connected on port " + stringify(clientPort));

Ik wil dus de integer die ik ontvang uit de clientData struct omvormen naar een string om zo wat output te verkrijgen (vergeef me de mogelijke beginnersfouten, het is mijn kennismaking met C++ en networking :)).

Hierover klaagt mijn linker echter als volgt:
code:
1
server.cpp:(.text+0x551)||undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> > stringify<int>(int const&)'|


Ik heb al talloze variaties daarop geprobeerd (want ik vermoed dat het probleem bij mijn header defenition ligt), maar niks bood soelaas. Ook las ik ergens dat je het "export" keyword zou moeten gebruiken, maar dat was enkel bij een class template. Ook klaagde mijn compiler dan dat het een unrecognized keyword was, en dus genegeerd zou worden.


Als iemand mij een duwtje in de goede richting zou kunnen geven :*)
maleadt

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Je compiler is inderdaad met grote waarschijnlijkheid gebrekkig. Export is theoretisch de meest correcte oplossing. De praktijkoplossing is om je template te inlinen, en dus in de header te definieren.

PS. de standaard "stringify"wordt meestal ostream& operator<<(std::ostream&, T const&) genoemd.

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


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Gewoon je template in de header definieren; dat doet iedereen...

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:04

.oisyn

Moderator Devschuur®

Demotivational Speaker

MSalters schreef op donderdag 07 augustus 2008 @ 21:34:
PS. de standaard "stringify"wordt meestal ostream& operator<<(std::ostream&, T const&) genoemd.
Die een ostream vereist, wat imho nogal onhandig werkt als je ergens gewoon even een string nodig hebt. Ik zie het probleem van de TS' wrapper eigenlijk niet helemaal?

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.


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ik gebruik idd exact dezelfde toString() functie in mijn code...

  • maleadt
  • Registratie: Januari 2006
  • Laatst online: 05-11 22:08
Zoijar schreef op donderdag 07 augustus 2008 @ 22:49:
Gewoon je template in de header definieren; dat doet iedereen...
Dus de hele functie verhuizen naar de header? Vloekt dat niet met wat ik overal lees, dat de header gewoon de functiebeschrijving moet bevatten, en de cpp dan de code zelf?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:04

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja wat wil je nou, de compiler heeft de definitie nodig want die support geen 'export' (bijna geen enkele compiler doet dat, en 'export' bleek een vergissing dus bijna geen enkele compiler gaat dat ook in de toekomst supporten). Dan kun je wel zeggen dat dat vloekt met bepaalde code guidelines, maar het is niet anders. Dus of je maakt een uitzondering op die guidelines, of je gebruikt gewoon geen templates :).

Er is trouwens niet wat je ervan weerhoudt om alsnog implementatie te scheiden van de interface, en die implementatie-file te includen vanuit de header waar de template definitie in staat.

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.


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

MALEADt schreef op vrijdag 08 augustus 2008 @ 11:55:
Dus de hele functie verhuizen naar de header? Vloekt dat niet met wat ik overal lees, dat de header gewoon de functiebeschrijving moet bevatten, en de cpp dan de code zelf?
Ik vind het heerlijk, header-only libraries. Volop ruimte om hard te optimizen, geen gedoe met libraries compilen en linken, geen verschillende CRTs, etc. Common practice is om de declaraties in een xxx.h(pp) file te zetten, en dan onderaan een <impl/xxx.cxx> te includen met de definities.

Als het perse wilt zonder export, dan moet je je template functie instantieren in je .cpp file, maar dan kan je hem alleen gebruiken voor die types. Verre van ideaal.

  • ATS
  • Registratie: September 2001
  • Laatst online: 29-10 18:37

ATS

Includen van je implementatie vanuit je header is inderdaad een goede oplossing. Werkt prima. Uiteraard zet je dan niet je implementatie file bij de bestanden die gebuild moeten worden in je makefile!

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant

Pagina: 1