🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: be.comp.programming
17 messages
17 total messages Started by Johan Vervloet Wed, 28 May 2003 11:49
[C++] function overloading en typedef
#4981
Author: Johan Vervloet
Date: Wed, 28 May 2003 11:49
33 lines
1730 bytes
Hallo,

Ik zit met een probleem gelijkaardig aan het volgende :

Stel ik heb een klasse GekleurdeInt, en ik wil die als volgt definieren :

        typedef int Kleur;      // proper niwaar :-)

        class GekleurdeInt
        {
        public:
                GekleurdeInt( int i );
                GekleurdeInt( Kleur k );
        /* enz */
        };

Dit werkt dus niet, aangezien int en Kleur voor de compiler van hetzelfde
datatype zijn.

Bestaat er hiervoor een mooie oplossing, zonder hiervoor een hele nieuwe
klasse Kleur te moeten maken ?

Bedankt,

Johan



-- 
  /"\  ASCII Ribbon Campaign
  \ /  against HTML email and proprietary formats
   X   
  / \  http://www.gewestpallieter.be/~johan/asciirib.php
Re: [C++] function overloading en typedef
#4982
Author: Roel Schroeven
Date: Wed, 28 May 2003 11:58
29 lines
1915 bytes
Johan Vervloet wrote:

> Hallo,
> 
> Ik zit met een probleem gelijkaardig aan het volgende :
> 
> Stel ik heb een klasse GekleurdeInt, en ik wil die als volgt definieren :
> 
>         typedef int Kleur;      // proper niwaar :-)
> 
>         class GekleurdeInt
>         {
>         public:
>                 GekleurdeInt( int i );
>                 GekleurdeInt( Kleur k );
>         /* enz */
>         };
> 
> Dit werkt dus niet, aangezien int en Kleur voor de compiler van hetzelfde
> datatype zijn.
> 
> Bestaat er hiervoor een mooie oplossing, zonder hiervoor een hele nieuwe
> klasse Kleur te moeten maken ?

Gewoon de eerste constructor weglaten?

-- 
"Codito ergo sum"
Roel Schroeven
Re: [C++] function overloading en typedef
#4983
Author: Johan Vervloet
Date: Wed, 28 May 2003 12:26
18 lines
1507 bytes
Roel Schroeven wrote:

> 
> Gewoon de eerste constructor weglaten?

In dit geval lost dat veel op natuurlijk, maar in de echte versie van mijn
probleem heb ik zowel de constructor met een int als argument als de
constructor met de typedef nodig.

Johan

> 

-- 
  /"\  ASCII Ribbon Campaign
  \ /  against HTML email and proprietary formats
   X   
  / \  http://www.gewestpallieter.be/~johan/asciirib.php
Re: [C++] function overloading en typedef
#4984
Author: Dominique Devriese
Date: Wed, 28 May 2003 12:59
45 lines
2449 bytes
Johan Vervloet writes:

  Johan> Hallo, Ik zit met een probleem gelijkaardig aan het volgende
  Johan> :

  Johan> Stel ik heb een klasse GekleurdeInt, en ik wil die als volgt
  Johan> definieren :

  Johan>         typedef int Kleur; // proper niwaar :-)

  Johan>         class GekleurdeInt { public:
  Johan>                 GekleurdeInt( int i ); GekleurdeInt( Kleur k
  Johan>                 );
  Johan>         /* enz */ };

  Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler
  Johan> van hetzelfde datatype zijn.

  Johan> Bestaat er hiervoor een mooie oplossing, zonder hiervoor een
  Johan> hele nieuwe klasse Kleur te moeten maken ?

het zgn. "Named Constructor Idiom" [1] kan hier mss helpen ?

Kort samengevat wordt dat dus:

typedef int Kleur;

class GekleurdeInt
{
public:
        GekleurdeInt( int i, Kleur k );
        static GekleurdeInt fromInt( int i );
        static GekleurdeInt fromKleur( Kleur k );
};

sjuus
domi

Footnotes: 
[1]  http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.8

-- 
For he is the lambda and xdelta, and every opening parenthesis will be
closed at the end of all input.
(David Kastrup on alt.religion.emacs)
Re: [C++] function overloading en typedef
#4985
Author: Roel Schroeven
Date: Wed, 28 May 2003 13:13
59 lines
3038 bytes
Dominique Devriese wrote:
> Johan Vervloet writes:
> 
>   Johan> Hallo, Ik zit met een probleem gelijkaardig aan het volgende
>   Johan> :
> 
>   Johan> Stel ik heb een klasse GekleurdeInt, en ik wil die als volgt
>   Johan> definieren :
> 
>   Johan>         typedef int Kleur; // proper niwaar :-)
> 
>   Johan>         class GekleurdeInt { public:
>   Johan>                 GekleurdeInt( int i ); GekleurdeInt( Kleur k
>   Johan>                 );
>   Johan>         /* enz */ };
> 
>   Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler
>   Johan> van hetzelfde datatype zijn.
> 
>   Johan> Bestaat er hiervoor een mooie oplossing, zonder hiervoor een
>   Johan> hele nieuwe klasse Kleur te moeten maken ?
> 
> het zgn. "Named Constructor Idiom" [1] kan hier mss helpen ?
> 
> Kort samengevat wordt dat dus:
> 
> typedef int Kleur;
> 
> class GekleurdeInt
> {
> public:
>         GekleurdeInt( int i, Kleur k );
>         static GekleurdeInt fromInt( int i );
>         static GekleurdeInt fromKleur( Kleur k );
> };

GekleurdeInt foo = GekleurdeInt::fromInt(123);

Dat wil dan wel zeggen dat je bij elke initialisatie eerst een object 
gaat aanmaken, en het dan kopi�ren. Voor kleine klassen niet erg, voor 
grotere zaken is dat wel lastig.

Als je de objecten met new maakt is het geen probleem:

typedef int Kleur;

class GekleurdeInt
{
public:
         GekleurdeInt( int i, Kleur k );
         static GekleurdeInt* fromInt( int i );
         static GekleurdeInt* fromKleur( Kleur k );
};

GekleurdeInt *foo = GekleurdeInt::fromInt(123);

-- 
"Codito ergo sum"
Roel Schroeven
Re: [C++] function overloading en typedef
#4986
Author: Dominique Devriese
Date: Wed, 28 May 2003 13:30
27 lines
2493 bytes
Roel Schroeven writes:

  Johan> GekleurdeInt( int i ); GekleurdeInt( Kleur k ); /* enz */ };
  Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler

  Johan> van hetzelfde datatype zijn.  
  >> het zgn. "Named Constructor Idiom" [1] kan hier mss helpen ?

  Roel> GekleurdeInt foo = GekleurdeInt::fromInt(123);

  Roel> Dat wil dan wel zeggen dat je bij elke initialisatie eerst een
  Roel> object gaat aanmaken, en het dan kopi�ren. Voor kleine klassen
  Roel> niet erg, voor grotere zaken is dat wel lastig.

Je kan die static methodes inline maken, als je echt denkt dat dat een
probleem is.  Maar ik denk niet dat het kopieren van twee integers erg
grote problemen gaat opleveren, tenzij je het enorm veel keer doet, en
dan heb je andere problemen..
sjuus
domi

-- 
One cannot escape the feeling that these mathematical formulas have an
independent existence and an intelligence of their own, that they are
wiser htan we are, wiser even than their discoverers, that we get more
out of them than we put into them.
( Heinrich Hertz on Maxwell's equations for electromagnetism )
Re: [C++] function overloading en typedef
#4987
Author: Roel Schroeven
Date: Wed, 28 May 2003 13:32
34 lines
2705 bytes
Dominique Devriese wrote:

> Roel Schroeven writes:
> 
>   Johan> GekleurdeInt( int i ); GekleurdeInt( Kleur k ); /* enz */ };
>   Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler
> 
>   Johan> van hetzelfde datatype zijn.  
>   >> het zgn. "Named Constructor Idiom" [1] kan hier mss helpen ?
> 
>   Roel> GekleurdeInt foo = GekleurdeInt::fromInt(123);
> 
>   Roel> Dat wil dan wel zeggen dat je bij elke initialisatie eerst een
>   Roel> object gaat aanmaken, en het dan kopi�ren. Voor kleine klassen
>   Roel> niet erg, voor grotere zaken is dat wel lastig.
> 
> Je kan die static methodes inline maken, als je echt denkt dat dat een
> probleem is.

Dat helpt niet he: GekleurdeInt::fromInt(123) geeft een object als 
resultaat, inline of niet, en door foo = ... wordt heel dat object 
gekopieerd.

> Maar ik denk niet dat het kopieren van twee integers erg
> grote problemen gaat opleveren, tenzij je het enorm veel keer doet, en
> dan heb je andere problemen..

Dat is juist, als die klasse niet meer data bevat dan die twee ints zal 
het geen probleem zijn. Een oplossing die meer scalable is zou nog 
mooier zijn :)

-- 
"Codito ergo sum"
Roel Schroeven
Re: [C++] function overloading en typedef
#4988
Author: Bert Peers
Date: Wed, 28 May 2003 13:59
31 lines
2238 bytes
Johan Vervloet wrote:

>         typedef int Kleur;      // proper niwaar :-)

Nee, niet proper ;)  En wel hierom :

Een typedef is eigenlijk maar een veredelde macro.  Een hack
uit die goeie ouwe C tijd, om het toch nog een _beetje_
verstaanbaar te houden. ;)

Wat je eigenlijk zegt is : omdat je het niet ziet zitten om
van Kleur een klasse te maken, ga je al de kennis die nodig is
om het onderscheid te maken tussen Kleur en int (kennis die
normaal in die klasse zou zitten), gaan rondstrooien bij de
gebruikers van Kleur (zoals GekleurdeInt), maw je plaatst
de verantwoordelijkheid om het verschil te kennen tussen
Kleur en int bij de gebruikers van het concept, ipv in het
concept zelf.  Ik zou zeggen, ga d'rvoor en maak er gewoon
een struct van.  1 constructor en 1 operator int () en je
bent er van af ;)

>         class GekleurdeInt
>         {
>         public:
>                 GekleurdeInt( int i );
>                 GekleurdeInt( Kleur k );
>         /* enz */
>         };


Bert
Re: [C++] function overloading en typedef
#4991
Author: Dominique Devriese
Date: Wed, 28 May 2003 16:22
36 lines
2677 bytes
Roel Schroeven writes:

  Roel> Dominique Devriese wrote:
  >> Roel Schroeven writes:
  Johan> GekleurdeInt( int i ); GekleurdeInt( Kleur k ); /* enz */ };

  Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler
  Johan> van hetzelfde datatype zijn.  >> het zgn. "Named
  >> Constructor Idiom" [1] kan hier mss helpen ?

  Roel> GekleurdeInt foo = GekleurdeInt::fromInt(123);

  Roel> Dat wil dan wel zeggen dat je bij elke initialisatie eerst
  >> een

  Roel> object gaat aanmaken, en het dan kopi�ren. Voor kleine klassen
  Roel> niet erg, voor grotere zaken is dat wel lastig.
  >> Je kan die static methodes inline maken, als je echt denkt dat
  >> dat een
  >> probleem is.

  Roel> Dat helpt niet he: GekleurdeInt::fromInt(123) geeft een object
  Roel> als resultaat, inline of niet, en door foo = ... wordt heel
  Roel> dat object gekopieerd.

Hmm..  
Ik kan me vergissen, maar dit is toch een heel duidelijk voorbeeld van
een situatie waar een compiler de zgn. "return value optimisation" kan
en mag toepassen ?

sjuus
domi

-- 
VI is historically important, if "religiously evil;"
(Christopher Browne on alt.religion.emacs)
Re: [C++] function overloading en typedef
#5089
Author: Nicolas Barbier
Date: Wed, 28 May 2003 18:51
75 lines
3104 bytes
Roel Schroeven wrote:

> Dominique Devriese wrote:
> 
>> Roel Schroeven writes:
>> 
>>   Roel> GekleurdeInt foo = GekleurdeInt::fromInt(123);
>> 
>>   Roel> Dat wil dan wel zeggen dat je bij elke initialisatie eerst een
>>   Roel> object gaat aanmaken, en het dan kopi�ren. Voor kleine klassen
>>   Roel> niet erg, voor grotere zaken is dat wel lastig.
>> 
>> Je kan die static methodes inline maken, als je echt denkt dat dat een
>> probleem is.
> 
> Dat helpt niet he: GekleurdeInt::fromInt(123) geeft een object als
> resultaat, inline of niet, en door foo = ... wordt heel dat object
> gekopieerd.

/* test.cpp */
class Blaat {
public:
        Blaat(int i) {
                this->i = i;
        }
        static Blaat gimme() {
                return Blaat(5);
        }
private:
        int i;
};

extern void bliep(const Blaat &b);

int main()
{
        bliep(Blaat(1));
}

/* deel van test.s, gecompileerd met gcc 3.2, -O3, op een x86 ding */
.globl main
        .type   main,@function
main:
/* functie proloog */
.LFB1:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $8, %esp
.LCFI2:
/* maak argumenten voor call naar bliep klaar */
        andl    $-16, %esp
        subl    $12, %esp
        leal    -4(%ebp), %edx
        pushl   %edx
        movl    $1, -4(%ebp)
.LCFI3:
/* doe call */
        call    _Z5bliepRK5Blaat
        xorl    %eax, %eax
        leave
        ret

Hoewel ik had verwacht dat het eerste deel van de functie beter 
"samengeplakt" zou geworden zijn (de proloog wordt misschien nooit 
geoptimaliseerd ofzo?), zie je duidelijk dat het object nooit gekopieerd 
wordt.

Nog iets dat ik eigenaardig vind: met -fomit-frame-pointer blijft de 
functie perfect hetzelfde, zou je dan niet verwachten dat die %ebp rommel 
weggegooid zou worden?

-- 
Nicolas Barbier
Re: [C++] function overloading en typedef
#5090
Author: Bert Peers
Date: Wed, 28 May 2003 20:30
37 lines
2865 bytes
Nicolas Barbier wrote:
 >
>         static Blaat gimme() {
>                 return Blaat(5);
> 
> extern void bliep(const Blaat &b);
> int main()
> {
>         bliep(Blaat(1));
> 
> Hoewel ik had verwacht dat het eerste deel van de functie beter 
> "samengeplakt" zou geworden zijn (de proloog wordt misschien nooit 
> geoptimaliseerd ofzo?), zie je duidelijk dat het object nooit gekopieerd 
> wordt.

Euh, ik kan niet goed volgen vrees ik.  Was het niet je bedoeling
om iets te schrijven als bliep(Blaat::gimme()) ?  Maar dan nog
weet ik niet of dit helpt -- de copy constructor wordt aangeroepen
op het moment dat de return value van de functie in de "recipient"
terecht komt.  Als die recipient enkel een const& nodig heeft,
moet er niks gekopieerd worden.  Ik zou zelfs bijna zeker zeggen,
"..._mag_ er niks gekopieerd worden".

Nu, het klopt wel natuurlijk dat als de compiler kan verifieren
dat die copy constructor geen neveneffecten heeft (bv omdat ie
'm zelf heeft gegenereerd), hij die mag overslaan en de functie
meteen in de recipient mag laten constructen.

> Nog iets dat ik eigenaardig vind: met -fomit-frame-pointer blijft de 
> functie perfect hetzelfde, zou je dan niet verwachten dat die %ebp rommel 
> weggegooid zou worden?

Misschien enkel als er echt een tekort aan registers ontstaat ?
De disassembly blijft toch nog net iets verstaanbaarder met ebp,
vandaar misschien..  kweetniet :)

Bert
Re: [C++] function overloading en typedef
#5092
Author: Nicolas Barbier
Date: Wed, 28 May 2003 21:09
93 lines
3930 bytes
Bert Peers wrote:

> Nicolas Barbier wrote:
>  >
>>         static Blaat gimme() {
>>                 return Blaat(5);
>> 
>> extern void bliep(const Blaat &b);
>> int main()
>> {
>>         bliep(Blaat(1));
>> 
>> Hoewel ik had verwacht dat het eerste deel van de functie beter
>> "samengeplakt" zou geworden zijn (de proloog wordt misschien nooit
>> geoptimaliseerd ofzo?), zie je duidelijk dat het object nooit gekopieerd
>> wordt.
> 
> Euh, ik kan niet goed volgen vrees ik.  Was het niet je bedoeling
> om iets te schrijven als bliep(Blaat::gimme()) ?

/me slaps himself *dough* "stupid!"

Inderdaad, ik lijk even verward te zijn geweest ;-)

Hier volgt de correcte versie, die echter eveneens aantoont dat GCC dit kan 
wegoptimalizeren:

/* test.cpp */
class Blaat {
public:
        Blaat(int i) {
                this->i = i;
        }
        static Blaat gimme() {
                return Blaat(5);
        }
private:
        int i;
};

extern void bliep(const Blaat &b);

int main()
{
        bliep(Blaat::gimme());
        /* Hier vergeet ik iets te returnen, merk dat GCC daar zelfs met
           -Wall, -ansi en -pedantic niets op zegt, en dat er in de
           gegenereerde code zelfs voor gezorgd wordt dat er 0 wordt
           gereturnd? */
}

/* gedeelte van test.s */
.globl main
        .type   main,@function
main:
.LFB1:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $8, %esp
.LCFI2:
        andl    $-16, %esp
        subl    $12, %esp
        leal    -4(%ebp), %edx
        pushl   %edx
        movl    $5, -4(%ebp)
.LCFI3:
        call    _Z5bliepRK5Blaat
        xorl    %eax, %eax
        leave
        ret

> Maar dan nog weet ik niet of dit helpt -- de copy constructor wordt
> aangeroepen op het moment dat de return value van de functie in de
> "recipient" terecht komt.Als die recipient enkel een const& nodig heeft,
> moet er niks gekopieerd worden.  Ik zou zelfs bijna zeker zeggen,
> "..._mag_ er niks gekopieerd worden".

Ben je daar zeker van? Je bedoelt dus dan in dit geval de copy-constructur 
niet opgeroepen mag worden? Ik dacht altijd (puttende uit mijn absoluut 
onbenullige C++ kennis :-) dat hij altijd wordt aangeroepen als je een 
volledig object returnt uit een functie. Trouwens, waar zouden, bij een 
gemiddelde compiler, anders de bytes van het object blijven staan? De stack 
gaat meteen weer worden overschreven terwijl er via de referentie nog naar 
het object kan gerefereerd worden.

Die "bliep" functie had ik er eigenlijk alleen maar bijgezet om te 
voorkomen dat alles volledig zou worden weg-geoptimalizeerd :-) (niet 
getest of dat ook werkelijk zo zou zijn anders).

-- 
Nicolas Barbier
Re: [C++] function overloading en typedef
#5093
Author: Bert Peers
Date: Wed, 28 May 2003 22:14
52 lines
3684 bytes
Nicolas Barbier wrote:

> int main()
> {
>         bliep(Blaat::gimme());
>         /* Hier vergeet ik iets te returnen, merk dat GCC daar zelfs met
>            -Wall, -ansi en -pedantic niets op zegt, en dat er in de
>            gegenereerde code zelfs voor gezorgd wordt dat er 0 wordt
>            gereturnd? */

Dat is volgens de standaard.  Als je zonder return
statement uit een functie dondert die een int zou moeten
returnen, heb je undefined behavior, _behalve_ voor
main -- daar return je vanzelf 0 (zie 3.6.1.5).

>>Maar dan nog weet ik niet of dit helpt -- de copy constructor wordt
>>aangeroepen op het moment dat de return value van de functie in de
>>"recipient" terecht komt.Als die recipient enkel een const& nodig heeft,
>>moet er niks gekopieerd worden.  Ik zou zelfs bijna zeker zeggen,
>>"..._mag_ er niks gekopieerd worden".
> 
> Ben je daar zeker van? Je bedoelt dus dan in dit geval de copy-constructur 
> niet opgeroepen mag worden? Ik dacht altijd (puttende uit mijn absoluut 
> onbenullige C++ kennis :-) dat hij altijd wordt aangeroepen als je een 
> volledig object returnt uit een functie. Trouwens, waar zouden, bij een 
> gemiddelde compiler, anders de bytes van het object blijven staan?

Wel, de compiler is nu eenmaal verplicht om, als er een
const-reference naar een temporary gebruikt wordt als parameter,
te zorgen dat die temporary "lang genoeg" blijft hangen.

Denk maar aan het meer vertrouwde

void blabla (const std::string &s);
blabla ("yup");

Je kan die gimme zien als een "conversie" die van niks
een Blaat maakt...  Trouwens, of de copy c'tor nu aangeroepen
wordt of niet, het mysterie van de bytes wordt er niet minder
op : gezien het feit dat bliep een const Blaat& als argument
heeft, naar waar zou er dan eigenlijk gekopieerd worden ?
Antwoord : eveneens naar een onzichtbare Blaat die eventjes snel
wordt gealloceerd zodat bliep er een const& van kan krijgen.

De compiler heeft meer opties dan "heap of stack" :^)
In die zin klopt het dat er een kopie buiten
"de normale ruimte van de functie" (dwz de stack) wordt
gemaakt -- waar het om gaat is dat de copy constructor
daar niet voor (mag) gebruikt worden, enkel compiler magic.


Bert
Re: [C++] function overloading en typedef
#5095
Author: Nicolas Barbier
Date: Thu, 29 May 2003 11:03
83 lines
4098 bytes
Bert Peers wrote:

> Nicolas Barbier wrote:
> 
>> Bert Peers wrote:
>> 
>>>Maar dan nog weet ik niet of dit helpt -- de copy constructor wordt
>>>aangeroepen op het moment dat de return value van de functie in de
>>>"recipient" terecht komt.Als die recipient enkel een const& nodig heeft,
>>>moet er niks gekopieerd worden.  Ik zou zelfs bijna zeker zeggen,
>>>"..._mag_ er niks gekopieerd worden".
>> 
>> Ben je daar zeker van? Je bedoelt dus dan in dit geval de
>> copy-constructur niet opgeroepen mag worden? Ik dacht altijd (puttende
>> uit mijn absoluut onbenullige C++ kennis :-) dat hij altijd wordt
>> aangeroepen als je een volledig object returnt uit een functie. Trouwens,
>> waar zouden, bij een gemiddelde compiler, anders de bytes van het object
>> blijven staan?
> 
> Wel, de compiler is nu eenmaal verplicht om, als er een
> const-reference naar een temporary gebruikt wordt als parameter,
> te zorgen dat die temporary "lang genoeg" blijft hangen.
> 
> Denk maar aan het meer vertrouwde
> 
> void blabla (const std::string &s);
> blabla ("yup");
> 
> Je kan die gimme zien als een "conversie" die van niks
> een Blaat maakt...  Trouwens, of de copy c'tor nu aangeroepen
> wordt of niet, het mysterie van de bytes wordt er niet minder
> op : gezien het feit dat bliep een const Blaat& als argument
> heeft, naar waar zou er dan eigenlijk gekopieerd worden ?
> Antwoord : eveneens naar een onzichtbare Blaat die eventjes snel
> wordt gealloceerd zodat bliep er een const& van kan krijgen.
> 
> De compiler heeft meer opties dan "heap of stack" :^)
> In die zin klopt het dat er een kopie buiten
> "de normale ruimte van de functie" (dwz de stack) wordt
> gemaakt -- waar het om gaat is dat de copy constructor
> daar niet voor (mag) gebruikt worden, enkel compiler magic.

Ik leer weer bij over de semantiek van C++ :-).

/* test.cpp */
#include <iostream>

class Blaat {
public:
        Blaat(int i) {
                std::cout << "constructor" << std::endl;
        }
        Blaat(const Blaat &b) {
                std::cout << "copy constructor" << std::endl;
        }
        static Blaat gimme() {
                return Blaat(3);
        }
};

int main()
{
        Blaat a(Blaat::gimme());
        std::cout << "tussen a en b" << std::endl;
        Blaat b(a);
}

/* uitvoer */
constructor
tussen a en b
copy constructor

De semantiek van een functie die een object returnt is dus blijkbaar niet 
"kopieer het te returnen object (via de copy constructor) naar de 
ontvangende temporary van de aanroepende functie", maar eerder "de 
ontvangende temporary van de aanroepende functie is hetzelfde object als 
hetgeen gereturnd wordt".

Weet je toevallig ook nog waarom er geen copy constructor-aanroep gebeurt 
tussen "constructor" en "tussen a en b"? :-)

-- 
Nicolas Barbier
Re: [C++] function overloading en typedef
#5096
Author: Slayerke
Date: Thu, 29 May 2003 11:34
100 lines
4921 bytes
Nicolas Barbier wrote:

> Bert Peers wrote:
> 
>> Nicolas Barbier wrote:
>> 
>>> Bert Peers wrote:
>>> 
>>>>Maar dan nog weet ik niet of dit helpt -- de copy constructor wordt
>>>>aangeroepen op het moment dat de return value van de functie in de
>>>>"recipient" terecht komt.Als die recipient enkel een const& nodig heeft,
>>>>moet er niks gekopieerd worden.  Ik zou zelfs bijna zeker zeggen,
>>>>"..._mag_ er niks gekopieerd worden".
>>> 
>>> Ben je daar zeker van? Je bedoelt dus dan in dit geval de
>>> copy-constructur niet opgeroepen mag worden? Ik dacht altijd (puttende
>>> uit mijn absoluut onbenullige C++ kennis :-) dat hij altijd wordt
>>> aangeroepen als je een volledig object returnt uit een functie.
>>> Trouwens, waar zouden, bij een gemiddelde compiler, anders de bytes van
>>> het object blijven staan?
>> 
>> Wel, de compiler is nu eenmaal verplicht om, als er een
>> const-reference naar een temporary gebruikt wordt als parameter,
>> te zorgen dat die temporary "lang genoeg" blijft hangen.
>> 
>> Denk maar aan het meer vertrouwde
>> 
>> void blabla (const std::string &s);
>> blabla ("yup");
>> 
>> Je kan die gimme zien als een "conversie" die van niks
>> een Blaat maakt...  Trouwens, of de copy c'tor nu aangeroepen
>> wordt of niet, het mysterie van de bytes wordt er niet minder
>> op : gezien het feit dat bliep een const Blaat& als argument
>> heeft, naar waar zou er dan eigenlijk gekopieerd worden ?
>> Antwoord : eveneens naar een onzichtbare Blaat die eventjes snel
>> wordt gealloceerd zodat bliep er een const& van kan krijgen.
>> 
>> De compiler heeft meer opties dan "heap of stack" :^)
>> In die zin klopt het dat er een kopie buiten
>> "de normale ruimte van de functie" (dwz de stack) wordt
>> gemaakt -- waar het om gaat is dat de copy constructor
>> daar niet voor (mag) gebruikt worden, enkel compiler magic.
> 
> Ik leer weer bij over de semantiek van C++ :-).
> 
> /* test.cpp */
> #include <iostream>
> 
> class Blaat {
> public:
>         Blaat(int i) {
>                 std::cout << "constructor" << std::endl;
>         }
>         Blaat(const Blaat &b) {
>                 std::cout << "copy constructor" << std::endl;
>         }
>         static Blaat gimme() {
>                 return Blaat(3);
>         }
> };
> 
> int main()
> {
>         Blaat a(Blaat::gimme());
>         std::cout << "tussen a en b" << std::endl;
>         Blaat b(a);
> }
> 
> /* uitvoer */
> constructor
> tussen a en b
> copy constructor
> 
> De semantiek van een functie die een object returnt is dus blijkbaar niet
> "kopieer het te returnen object (via de copy constructor) naar de
> ontvangende temporary van de aanroepende functie", maar eerder "de
> ontvangende temporary van de aanroepende functie is hetzelfde object als
> hetgeen gereturnd wordt".
> 
> Weet je toevallig ook nog waarom er geen copy constructor-aanroep gebeurt
> tussen "constructor" en "tussen a en b"? :-)
> 
g++ heeft deze al weggeoptimaliseerd, dit moet expliciet afgezet worden:
-fno-elide-constructors
           The C++ standard allows an implementation to omit creating a
tempo-
           rary which is only used to initialize another object of the same
           type.  Specifying this option disables that optimization, and
           forces G++ to call the copy constructor in all cases.
Dan geeft het (zoals verwacht):
constructor
copy constructor
copy constructor
tussen a en b
copy constructor

-- 
Groeten,
Slayerke
Re: [C++] function overloading en typedef
#5097
Author: Nicolas Barbier
Date: Thu, 29 May 2003 11:57
30 lines
2146 bytes
Slayerke wrote:

> Nicolas Barbier wrote:

(snip)

>> Weet je toevallig ook nog waarom er geen copy constructor-aanroep gebeurt
>> tussen "constructor" en "tussen a en b"? :-)
> 
> g++ heeft deze al weggeoptimaliseerd, dit moet expliciet afgezet worden:
> -fno-elide-constructors
>            The C++ standard allows an implementation to omit creating a
> tempo-
>            rary which is only used to initialize another object of the
>            same
>            type.  Specifying this option disables that optimization, and
>            forces G++ to call the copy constructor in all cases.
> Dan geeft het (zoals verwacht):
> constructor
> copy constructor
> copy constructor
> tussen a en b
> copy constructor

*Aaaargl*, ik snap het. Ik moet gewoon de standaard lezen als ik de 
volledige semantiek van C++ wil kennen. Maar die wil begint weer snel af te 
brokkelen als ik dergelijke dingen zie ;-).

-- 
Nicolas Barbier
Re: [C++] function overloading en typedef
#5098
Author: Bert Peers
Date: Thu, 29 May 2003 13:38
28 lines
2088 bytes
Bert wrote:
>>>>>Als die recipient enkel een const& nodig heeft,
>>>>>moet er niks gekopieerd worden.

Slayerke wrote:
> -fno-elide-constructors
>
> Dan geeft het (zoals verwacht):
> constructor
> copy constructor
> copy constructor
> tussen a en b
> copy constructor
> 

Asjemenou !

6.6.3.2 : A return statement can involve the construction
and copy of a temporary object.

Daar wordt een mens niet wijzer van..  Misschien bedoelt
men met die "can" : "must, tenzij zoals voorzien in 12.8.15"...


Nu ja, tnx :)

Bert
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads