[C++] set<void*>::find(const void*) kan niet?

Pagina: 1
Acties:

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ik was wat code aan het editen en ik stuitte ineens op een vage foutmelding. Na wat meer editen kom ik op onderstaande code uit.
Waarom kan ik niet zoeken naar een const void*?
a is niet const, en b wordt door find toch niet veranderd?

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <set>

using namespace std;

int main()
{
        typedef set<void*> t_a;
        t_a a;
        const void* b;
        a.find(b);
        return 0;

}

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:14
b is geen const-variabele, maar een non-const pointer naar (const void). find() krijgt echter een (const (void*) &) argument en dat is duidelijk niet compatible met ((const void *) &) ; daarvoor zou immer ((const void)*) impliciet naar (void*) geconverteerd moeten worden. (De type-notaties die ik gebruikte zijn trouwens slechts ter illustratie en kun je niet direct gebruiken; ik denk dat mede daarom je set een key_type member kent.)

Jouw voorbeeld werkt wel als je je declaratie wijzigt in "void* const b = 0;" want dan declareer je een const-variabele van het type (void*) en die kun je wel gebruiken om te zoeken in een set van (void*)'s.

Beetje wazig verhaal geworden; kun je het een beetje volgen of moet ik een poging doen het duidelijker te formuleren?

[ Voor 13% gewijzigd door Soultaker op 25-03-2004 21:22 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 10:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

set::find verwacht een const reference naar een void *. Dat is wat anders dan een const reference naar een const void *.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void f1 (void *&);
void f2 (const void *&);

void f3 (void * const &);
void f4 (const void * const &);

int main() 
{
    void * a;
    const void * b;

    f1 (a);
    f2 (a); // fout
    f3 (a);
    f4 (a);

    f1 (b); // fout
    f2 (b);
    f3 (b); // fout
    f4 (b);
}


f3 (b) is jouw situatie.

f2 (a) gaat natuurlijk fout omdat f2 een non-const reference verwacht naar een const void *, hij moet de pointer kunnen veranderen en er kan dus geen temporary gemaakt worden.

Hetzelfde geldt voor f1 (b), die verwacht nou juist een void * terwijl je een const void * geeft

f3 (b) vereist een cast van const void * naar void *, wat natuurlijk niet impliciet mag. Feitelijk is het hetzelfde als een const void * geven aan een functie die een void * verwacht

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.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Soultaker schreef op 25 maart 2004 @ 21:21:
Beetje wazig verhaal geworden; kun je het een beetje volgen of moet ik een poging doen het duidelijker te formuleren?
Ik snap het een beetje, maar wat wil find met b doen dan wat nu niet kan?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 10:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je ziet de const verkeerd. B zelf is niet const, datgene waar b naar wijst is const. De find functie wil nou juist een pointer naar een void die niet const is (omdat jij dat zo gespecificeerd hebt in de set), en die const kun je niet impliciet wegcasten

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.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Dat snap ik, maar dat is toch niet noodzakelijk voor de functionaliteit van find (als het argument geen problemen zou opleveren)?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 10:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

:?
Ik volg je 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.


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

OlafvdSpek schreef op 25 maart 2004 @ 22:33:
Dat snap ik, maar dat is toch niet noodzakelijk voor de functionaliteit van find (als het argument geen problemen zou opleveren)?
Het gaat er meer om wat find zou *kunnen* doen ipv wat ie echt doet. b is een non-const pointer naar een const 'iets'. Stel dat de cast toegestaan was. Dan heeft find een const pointer (reference) naar een non-const 'iets'. In principe zou find dus via die pointer het 'iets' kunnen aanpassen, terwijl jij juist had aangegeven dat dat niet mocht door b naar een const 'iets' te laten wijzen. Find zal wel alleen met de pointer zelf werken en die gaan vergelijken met die in de set, maar daar weet de compiler niks van. Voor hetzelfde geld doet find wel iets met de data waar de pointer naar wijst. De compiler let alleen op het type dat je geeft, en het type dat de functie wil, ziet dat een cast niet 100% zeker kan zonder de const garantie te verbreken (ookal zal dat met find in de praktijk niet gebeuren), en geeft een error.

[ Voor 7% gewijzigd door madwizard op 25-03-2004 23:40 ]

www.madwizard.org


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 10:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

Oh bedoelde ie het zo 8)7
*eens met madwizard* :P

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.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Bedankt madwizard, dat was het inderdaad.

Maar eh, als ik de find code zelf 'inline', dan mag het wel.
Als workaround maak ik de member functie waar find in gebruikt wordt niet const, maar dat is natuurlijk niet zo netjes.
Is er geen betere oplossing?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 10:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik vrees het niet, je zult gewoon gebruik moeten maken van een const_cast. Niet de mooiste oplossing natuurlijk, maar op zich niet zo erg aangezien je weet dat de find functie toch niet de data zal wijzigen (bovendien, als je 'm gevonden hebt en je leest hem uit dan is het vervolgens weer een non-const void * die je weer heel leuk zelf aan kunt passen, terwijl het dezelfde pointer is als die const void * die je oorspronkelijk had ;))

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