2015-12-09 12 views
5

Ich versuche, mein C++ zu verstehen, warum Compiler mit dem folgenden Code verwechselt wird:Fehler: mehrdeutig Überlastung für 'operator =='

struct Enum 
{ 
    enum Type 
    { 
    T1, 
    T2 
    }; 
    Enum(Type t):t_(t){} 
    operator Type() const { return t_; } 
private: 
    Type t_; 
    // prevent automatic conversion for any other built-in types such as bool, int, etc 
    template<typename T> operator T() const; 
}; 

    enum Type2 
    { 
    T1, 
    T2 
    }; 

int main() 
{ 
    bool b; 
    Type2 e1 = T1; 
    Type2 e2 = T2; 
    b = e1 == e2; 

    Enum t1 = Enum::T1; 
    Enum t2 = Enum::T2; 
    b = t1 == t2; 
    return 0; 
} 

Compilation führt zu:

$ c++ enum.cxx 
enum.cxx: In function ‘int main()’: 
enum.cxx:30:10: error: ambiguous overload for ‘operator==’ (operand types are ‘Enum’ and ‘Enum’) 
    b = t1 == t2; 
     ^
enum.cxx:30:10: note: candidates are: 
enum.cxx:30:10: note: operator==(Enum::Type, Enum::Type) <built-in> 
enum.cxx:30:10: note: operator==(int, int) <built-in> 

I verstehen, dass ich die Symptome, indem eine explizite operator== lösen kann:

bool operator==(Enum const &rhs) { return t_ == rhs.t_; } 

Aber wirklich Was ich suche, ist die Interpretation, warum der Vergleich enum nur dann zu einer Mehrdeutigkeit führt, wenn es innerhalb einer class gemacht wird. Ich habe diesen kleinen enum-Wrapper geschrieben, da ich nur C++ 03 in meinem Code verwenden soll.

+3

Sie haben einen 'Operator T()', der die 'Enum' in ** irgendeinen ** Typ umwandelt. Das fordert viel Zweideutigkeit. –

Antwort

2

der Aufruf ist mehrdeutig, da sowohl die Enum::Type und int Versionen gelten mit einer einzigen impliziten Konvertierung sind, erstere mit der operator Type Umwandlung und das letzteres mit dem operator T Template Umwandlungsoperator.

012.

Es ist unklar, warum Sie eine Umwandlung in einen beliebigen Typ haben, aber wenn Sie diesen Operator entfernen, lautet der Code works.

Wenn Sie C++ 11 verwenden, sollten Sie stattdessen scoped enums verwenden.

+0

Ich versuchte hart * nicht * eine Art von Conversion zu haben ... siehe meinen Kommentar – malat

+0

Wenn Sie eine typsichere Enumeration in C++ 03 haben möchten, sollten Sie alle Operatoren selbst bereitstellen und nicht implizit in das Underlying konvertieren enum. – TartanLlama

0

enum implizit in int (so weit umgewandelt werden, wie ich es verstehe durch die Abwärtskompatibilität zu C verursacht wird. Wenn Sie C++11 verwenden können, können Sie enum class, um dieses Problem zu lösen, weil scoped Aufzählungen nicht implizite Konvertierung in int ermöglichen.

0

Enum ist Implementierung definiert Integraltyp, der meist int ist. Nun ist jeder Operator, den Sie für enum implementieren, so, als würden Sie den Operator für den Typ int implementieren. Eine Neudefinition des beliebigen Operators für ganzzahlige Typen wie int, double, char ... ist nicht erlaubt, da dies die Grundbedeutung der Programmiersprache selbst ändert.

Verwandte Themen