Avatar billede karas Nybegynder
07. december 2007 - 10:17 Der er 4 kommentarer

cast og ambiguity

Hej kvikke hoveder, jeg har et spørgsmål jeg håber i kan hjælpe med. Jeg arbejder på et projekt der compiles med både MSVC 8 og gcc 3.0.4, og gcc angiver ambiguity for noget code som MSVC ikke gør.

Mit spørgsmål er om det er en fejl i gcc eller om det er en fejl at MSVC ikke rapporterer den.
Burde "static_cast<T>(X)" ikke favorisere "X::operator T()" i stedet for "T( X::operator int() )" ? Det er hvad MSVC 8 gør.

Følgende er koden
{
    SubSystemEntityId s( 12345 );
    static_cast<ComponentId>(s); // <- Vil ikke compile med gcc
    ComponentId(s); // <- Vil ikke compile med gcc
    s.operator ComponentId(); // Virker
}

Følgende er definitionen på de to klasser:

class SubSystemEntityId
{
public:
    SubSystemEntityId(int id = 0);
 
    SubSystemEntityId operator=(ComponentId componentId);

    operator ComponentId() const;
    operator int() const;

private:
    int m_id;
};

class ComponentId
{
public:
    explicit ComponentId(int id = 0) { set(id); }

    ComponentId operator=(int id);

    ComponentId operator++();
    ComponentId operator++(int);
    ComponentId operator--();
    ComponentId operator--(int);

    operator int() const;

private:
    int set(int id);   

private:
    int m_id;
};

Følgende er fejlbeskeden fra gcc:

[cpptasks:cc] /home/xkika/src/iqprobe/VoIPTracker/src/test/common/TestSubSystemEntityId.cpp: In
[cpptasks:cc]    member function `void TestSubSystemEntityId::testConstructor()':
[cpptasks:cc] /home/xkika/src/iqprobe/VoIPTracker/src/test/common/TestSubSystemEntityId.cpp:47: call
[cpptasks:cc]    of overloaded `ComponentId(SubSystemEntityId&)' is ambiguous
[cpptasks:cc] /home/xkika/src/iqprobe/VoIPTracker/src/common/component/ComponentId.h:25: candidates
[cpptasks:cc]    are: ComponentId::ComponentId(const ComponentId&)
[cpptasks:cc] /home/xkika/src/iqprobe/VoIPTracker/src/common/component/ComponentId.h:27:
[cpptasks:cc]              ComponentId::ComponentId(int = 0)
Avatar billede stormy Nybegynder
07. december 2007 - 11:19 #1
Jeg ved ikke om det er en fejl, ud fra mit kendskab til C++ kræver dit cast, at et temporært objekt bliver oprettet. Og du angiver at du ønsker et objekt af typen ComponentId - så jeg er ikke sikker på at "explicit" hjælper (i denne kontekst!).

Men en mulighed for at sikre en utvetydig konversion kunne være at definere følgende konstruktor:

ComponentId::ComponentId( const SystemEntityId& )
Avatar billede karas Nybegynder
07. december 2007 - 13:04 #2
Jeg ville tro at brugen af static_cast<T> auotamtisk ville prioritere operator T() øverst.

Jeg kan ikke gøre ComponentId afhængig af SubSystemEntityId og SubSystemEntityId::operator int() må ikke blive kaldt da SubSystemEntityId repræsenterer en 32 bit integer og ComponentId en 8 bit integer (SubSystemEntityId er sammensat af et ComponentId og et andet id på 24 bit).
Avatar billede lars314 Nybegynder
11. december 2007 - 22:45 #3
Du bruger jo ikke den cast'ede værdi til noget (hvorfor egentligt ikke)

Hvad med:
ComponentId ci = static_cast<ComponentId>(s);
Avatar billede lars314 Nybegynder
11. december 2007 - 22:48 #4
ComponentId(s);

er jo klar nok, mener du
ComponentId(s::operator ComponentId() const);
eller
ComponentId(s::operator int() const);
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester