[C++] const reference parameter met default value

Pagina: 1
Acties:

  • Yodah
  • Registratie: Juni 2005
  • Laatst online: 19-11 13:46
Hi,

Ik wil het volgende doen:

void blaat(const std::map<std::string, std::string> & myMap = std::map<std::string, std::string>());

Oftewel functie declaratie met een const reference map parameter. Deze map wil ik default initialiseren met een lege map. Ik krijg dit de compiler niet door de strot gedrukt, wat resulteert in de volgende errors:

src/../include/**********.h:50: error: expected `,' or `...' before '>' token
src/../include/**********.h:50: error: missing `>' to terminate the template argument list
src/../include/**********.h:50: error: wrong number of template arguments (1, should be 4)

Heb hetzelfde geprobeerd met een vector en dat werkt wel
void blaat(const std::vector<std::string> & myVector = std::vector<std::string>());

Ik heb al vanalles geprobeerd en gezocht, maar ik krijg het niet voor elkaar. Volgens mij moet het wel gewoon kunnen maar ik heb het idee dat ik iets fout doe in de constructor van de empty map.

Kan iemand mij uitleggen wat ik fout doe?

Mvg

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Hmmm bij mij compiled dit gewoon (VC++2005). Welke compiler gebruik je?

[edit]
Wat wil je eigenlijk met een nieuwe lege vector/map doen als hij const is? :)

[ Voor 63% gewijzigd door farlane op 16-03-2007 12:06 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Yodah
  • Registratie: Juni 2005
  • Laatst online: 19-11 13:46
btw. ik gebruik een gnu compiler op een 32bits linux bak.
De const reference lijkt er niets mee te maken te hebben trouwens.

void blaat(std::map<std::string, std::string> myMap = std::map<std::string, std::string>());

Dit geeft dezelfde errors.
farlane schreef op vrijdag 16 maart 2007 @ 12:05:
Hmmm bij mij compiled dit gewoon (VC++2005). Welke compiler gebruik je?

[edit]
Wat wil je eigenlijk met een nieuwe lege vector/map doen als hij const is? :)
Als hij leeg is wil ik er natuurlijk niks mee doen, het is dan ook een default value die alleen gebruikt wordt wanneer er in de functie call geen map parameter gegeven wordt.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Yodah schreef op vrijdag 16 maart 2007 @ 12:10:
Als hij leeg is wil ik er natuurlijk niks mee doen, het is dan ook een default value die alleen gebruikt wordt wanneer er in de functie call geen map parameter gegeven wordt.
Is dat niet een beetje een dure manier om te voorkomen dat je een verkeerde pointer meekrijgt? Ik bedoel je kunt deze functie alleen maar aanroepen met of geen enkele parameter( en in dat geval heb je er niets aan ) of met een geldige map variabele.
btw. ik gebruik een gnu compiler op een 32bits linux bak
versie?

[ Voor 7% gewijzigd door farlane op 16-03-2007 13:23 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Yodah
  • Registratie: Juni 2005
  • Laatst online: 19-11 13:46
gcc version 3.4.4 20050721 (Red Hat 3.4.4-2)

Hoezo trouwens 'dure' manier?

Het idee van die default is dat ik een parameter toevoeg aan een bestaande functie. Er zijn heel veel plekken waar deze functie al gecalled wordt en waar de nieuwe parameter niet nodig is. Slechts voor enkele nieuwe gevallen wil ik functionaliteit toevoegen. Vandaar de default lege map.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Yodah schreef op vrijdag 16 maart 2007 @ 13:29:
gcc version 3.4.4 20050721 (Red Hat 3.4.4-2)
Hoezo trouwens 'dure' manier?
Er zijn heel veel plekken waar deze functie al gecalled wordt en waar de nieuwe parameter niet nodig is.
Daar doelde ik op. De functie wordt dus op heel veel plekken aangeroepen waarbij die map niet nodig is maar wel geinstantieerd wordt.

Voor hetzelfde geld maakt het h*l uit maar ik zou in dat geval voor een pointer parameter met default waarde 0 kiezen ofzo.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Yodah
  • Registratie: Juni 2005
  • Laatst online: 19-11 13:46
farlane schreef op vrijdag 16 maart 2007 @ 13:36:
[...]


Voor hetzelfde geld maakt het h*l uit maar ik zou in dat geval voor een pointer parameter met default waarde 0 kiezen ofzo.
Ok op die manier. Dat zou een optie kunnen zijn. Helaas moeten andere compilers (waaronder een aantal exotisch dat ook trekken). Bv. gcc 4.0.2, toch niet de meest strikte compiler, ondersteund dat niet.

Ik heb het inmiddels wel werkende maar nogal omslachtig. Buiten de vraag of ik het op de slimste (of meest efficiente) manier doe ben ik nog steeds wel benieuwd waarom mijn compiler mijn initiele code niet slikt.

@farlane, in ieder geval bedankt voor het meedenken!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Yodah schreef op vrijdag 16 maart 2007 @ 13:49:
Ok op die manier. Dat zou een optie kunnen zijn. Helaas moeten andere compilers (waaronder een aantal exotisch dat ook trekken). Bv. gcc 4.0.2, toch niet de meest strikte compiler, ondersteund dat niet.
deze code
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <string>
#include <vector>
#include <map>

void blaat1( const std::vector<std::string> & myVector = std::vector<std::string>() )
{}

void blaat2( const std::map<std::string, std::string>& myMap = std::map<std::string,std::string>() )
{}

void blaat3( const std::map<std::string, std::string> * myMap = 0 )
{}

int main( int argc, char * argv[] )
{
}

wordt door Mingw ( gcc 3.2.3 ) prima gecompileerd dus ik denk dat je iets anders fout doet

[edit]
Ik neem aan dat je wel string include ? :)

[ Voor 3% gewijzigd door farlane op 16-03-2007 14:12 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Yodah
  • Registratie: Juni 2005
  • Laatst online: 19-11 13:46
Nogmaals thanx voor de moeite.

Yep includes zijn fine :)

Ik heb de hoop al bijna opgegeven.
Op mijn gcc 3.4.4 werken de bovenstaande blaat1 en blaat 3, maar blaat 2 niet.
Op mijn 2e machine gcc4.0.2 werkt alleen blaat1, maar blaat2 en 3 niet.

Over sun, hp en 64 bit compilers durf ik nog niet na te denken :p

Helaas kan ik door al die platformen niet altijd de meest voor de hand liggende manier kiezen. Ik declareer de lege map nu buiten de functie declaratie en assign hem in de functie declaratie als default value aan de map variabele. Dit is niet echt een cleane methode maar het werkt. Als iemand kan verklaren waarom bovenstaande blaat2 functie niet door alle compilers wordt geaccepteerd dan hoor ik dat nog graag!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Yodah schreef op vrijdag 16 maart 2007 @ 14:23:
Nogmaals thanx voor de moeite.

Yep includes zijn fine :)

Ik heb de hoop al bijna opgegeven.
Op mijn gcc 3.4.4 werken de bovenstaande blaat1 en blaat 3, maar blaat 2 niet.
Op mijn 2e machine gcc4.0.2 werkt alleen blaat1, maar blaat2 en 3 niet.

Over sun, hp en 64 bit compilers durf ik nog niet na te denken :p

Helaas kan ik door al die platformen niet altijd de meest voor de hand liggende manier kiezen. Ik declareer de lege map nu buiten de functie declaratie en assign hem in de functie declaratie als default value aan de map variabele. Dit is niet echt een cleane methode maar het werkt. Als iemand kan verklaren waarom bovenstaande blaat2 functie niet door alle compilers wordt geaccepteerd dan hoor ik dat nog graag!
Raar.

Als het een nieuwe parameter op een bestaande functie is kun je ook overwegen om van overloading gebruik te maken.

C++:
1
2
3
4
5
void blaat( int a, int b )
{}

void blaat( int a, int b, const std::map<std::string, std::string>& myMap )
{}


BTW het lijkt er een beetje op dat de compiler template argumenten mist in je 1e versie. Probeer het eens door alle template parameters op te geven zodat er geen misverstand kan bestaan over welke types de compiler moet gebruiken voor het template.

[ Voor 10% gewijzigd door farlane op 16-03-2007 14:59 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Yodah
  • Registratie: Juni 2005
  • Laatst online: 19-11 13:46
Dat zal het inderdaad wel zijn ja. Zal er een mental note van maken en er volgende week nog eens naar kijken. Dit is geen werk voor vrijdagmiddag :p.

  • schoene
  • Registratie: Maart 2003
  • Laatst online: 01-12 16:07
Heb je je map al eens ge-typedef-t? In BCB6 gaf jouw code ook problemen, maar met te typedef-en was het probleem opgelost

C++:
1
2
typedef std::map <std::string, std::string> AMap ;
void blaat(const  AMap& myMap = AMap ());

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

farlane schreef op vrijdag 16 maart 2007 @ 13:36:

Daar doelde ik op. De functie wordt dus op heel veel plekken aangeroepen waarbij die map niet nodig is maar wel geinstantieerd wordt.
Een lege map of vector initialiseren is niet duur :)

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.


  • Yodah
  • Registratie: Juni 2005
  • Laatst online: 19-11 13:46
Die typedef werkt inderdaad overal! Dat is wel wat netter dan een global empty map :p

Thanx

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Wel loos trouwens, ik had gcc hoger ingeschat. Maar goed, 't is ook een vrij oude versie.

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.


  • Yodah
  • Registratie: Juni 2005
  • Laatst online: 19-11 13:46
Je verbaast je erover hoeveel weirde dingen je tegenkomt als je verschillende compilers gebruikt. Ik ben zeker geen C++ guru die allerlei exotische dingen codeerd, maar ik heb regelmatig dat heel normale code op verschillende 'standaard' compilers ineens wel, geen of verschillende errors en warnings geeft. Zal ook wel aan C++ liggen.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik denk dat dat eerder ligt aan het feit dat de compilers er eerder waren dan dat C++ officieel gestandaardiseerd was (in '98), waardoor ze allemaal met een oude incompliant codebase hebben te kampen :).

Overigens, als je echte compliant C++ wilt schrijven kan ik je Comeau aanraden. Die compileert je C++ code naar C code waardoor het op een enorm breed scala aan architecturen werkt.

[ Voor 37% gewijzigd door .oisyn op 16-03-2007 17:02 ]

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

Yodah schreef op vrijdag 16 maart 2007 @ 11:14:
void blaat(const std::map<std::string, std::string> & myMap = std::map<std::string, std::string>());

Oftewel functie declaratie met een const reference map parameter. Deze map wil ik default initialiseren met een lege map. Ik krijg dit de compiler niet door de strot gedrukt...
Inderdaad, compilers als gcc en CodeWarrior doen daar moeilijk over. Het probleem zit 'm in de komma in je default argument, want dat is een "non-parenthesized" komma en daar is de spec nogal vaag over. Voor de gore details kun je bvb terecht in dit document, meer bepaald het stuk "325. When are default arguments parsed?".

Als ik me niet vergis is dit probleem ook al een kleine eeuwigheid bekend in gcc's bugzilla. Ik herinner me toch vaag dat Andrew (Pinski) me ooit naar aanleiding van een gelijkaardig bugrapport meldde dat men wacht met verdere stappen nemen tot de vage delen in de spec zijn opgehelderd...
Heb hetzelfde geprobeerd met een vector en dat werkt wel
void blaat(const std::vector<std::string> & myVector = std::vector<std::string>());
Geen komma in het default argument, dus geen probleem :)

Een typedef is in dit geval je vriend, zoals schoene aangeeft :)

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
.oisyn schreef op vrijdag 16 maart 2007 @ 16:24:
Een lege map of vector initialiseren is niet duur :)
Het zal ongetwijfeld niet zo heel veel uitmaken, maar als het op een andere manier mooier op te lossen is die het niet nodig heeft is het omega% duurder dan nodig is :P
( als het idd een nieuwe versie van een bestaande functie is zou ik indien mogelijk voor de overloaded versie gaan. )
Wel loos trouwens, ik had gcc hoger ingeschat. Maar goed, 't is ook een vrij oude versie
Das dus het rare eraan, ik heb em gecompiled met een oudere versie van gcc ( weliswaar mingw ) en die ging wel goed. Misschieen dat mingw meer/andere patches heeft oid?
Overigens, als je echte compliant C++ wilt schrijven kan ik je Comeau aanraden.
Gebruiken jij die ook voor het cross platform schrijven van games?

[ Voor 20% gewijzigd door farlane op 17-03-2007 12:14 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

farlane schreef op zaterdag 17 maart 2007 @ 12:10:
[...]

Het zal ongetwijfeld niet zo heel veel uitmaken, maar als het op een andere manier mooier op te lossen is die het niet nodig heeft is het omega% duurder dan nodig is :P
Maar that's the whole point, ik vind een pointer alles behalve mooier, omdat dat semantisch gewoon heel iets anders betekent. En als je een overload maakt heb je óf twee functies om te maintainen, óf de ene roept de ander weer aan waardoor je alsnog een lege container zit te maken (of je maakt een globale lege map zodat je de initialisatie van 3 pointers en een int op 0 kunt voorkomen 8)7)
Gebruiken jij die ook voor het cross platform schrijven van games?
Nee, we gebruiken VC++ 7.1 voor win32, Xbox en Xbox 360 (technisch gezien is de Xbox 360 compiler eigenlijk een fork van een early VC++ 8.0), en gemodificeerde gcc's voor GC, PS2 en PS3. Comeau is denk ik niet zo handig omdat alle SIMD intrinsics dan waarschijnlijk verloren gaan.

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.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 11:55
In de Xbox zit toch gewoon een Intel x86 processor? Waarom heb je daar een aparte compiler voor nodig? Of is het alleen een andere linker?

edit:
Ah, hmm, ik had krom gelezen. 8)7

[ Voor 15% gewijzigd door Soultaker op 17-03-2007 17:49 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

:?
Nee, we gebruiken VC++ 7.1 voor win32, Xbox en Xbox 360 (technisch gezien is de Xbox 360 compiler eigenlijk een fork van een early VC++ 8.0)
Daar staat toch niet dat we een andere compiler gebruiken? :). In de Xbox 360 zit trouwens een gemodificeerde PowerPC, dus vandaar dat die wel anders is.

[ Voor 6% gewijzigd door .oisyn op 17-03-2007 17:28 ]

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.

Pagina: 1