5

Rozważmy następujący przykład:zdefiniowany przez użytkownika niejawna konwersja z klasy enum gdy wywołanie przeciążony operator nie

struct ConvertibleStruct {}; 

enum class ConvertibleEC {}; 

struct Target { 
    // Implicit conversion constructors 
    Target(ConvertibleStruct) {} 
    Target(ConvertibleEC) {} 
}; 

Target operator~(const Target& t) { 
    return t; 
} 

Target anotherFunction(const Target& t) { 
    return t; 
} 

int main() { 
    ConvertibleStruct t; 
    ConvertibleEC ec; 

    ~t;     // 1. Works finding the operator overloaded above 
    ~ec;     // 2. Fails to compile on clang 3.4 and gcc 4.8.2 
    operator~(ec);  // 3. Works finding the operator overloaded above 

    anotherFunction(ec); // 4. Works 
} 

kompilatora wersjach:

Powyższe ustalenia są dla clang 3.4 i gcc 4.8.2. Test 2. faktycznie kompiluje dobrze na gcc 4.7.3 z -std=c++11. Prawdopodobnie błąd we wczesnej implementacji GCC C++ 11?

Asercje:

  • Zważywszy, że 1. kompiluje, zdefiniowane przez użytkownika konwersje niejawne-sprawdzane są przy wywołaniu operatora ~.
  • Biorąc pod uwagę, że 4. kompilacje, zdefiniowane przez użytkownika niejawne konwersje są sprawdzane pod kątem obiektów enum class.

Pytania:

  • Czy powyższe stwierdzenia są prawidłowe?
  • Jeśli tak, dlaczego 2. nie można skompilować?
  • Biorąc pod uwagę, że 2. nie można skompilować, dlaczego 3. kompiluje?

Odpowiedz

4

Drugi test, ~ec biegnie do specyfiki nazwą odnośnika dla operatorów w wyrażeniach: [over.match.oper]/3 (z "dawnej" N3797):

Dla operatorem, @ z argumentu typu którego CV niewykwalifikowany wersja T1 [...]

zestaw kandydatów trzecich jest wynikiem uwarunkowanej odnośnika z [email protected] w kontekście ekspresji według usua l reguł wyszukiwania nazw w niewykwalifikowanych wywołaniach funkcji z tym wyjątkiem, że wszystkie funkcje składowe są ignorowane. Jednakże, jeśli nie operand ma typ klasy, tylko te funkcje trzecimi w wyszukiwarkę ustawić że mają pierwszy parametr typu T1 lub „Odniesienie do (ewentualnie cv wykwalifikowany) T1”, gdy T1 stanowi wyliczenie typ [...] to funkcje kandydujące.

::operator~(const Target&) więc nie powinno się znaleźć/używane z za wyraz z operatorem jednoargumentowego stosowany do argumentu typu ConvertibleEC.


Dla pierwszego, ~t, operand jest typu klasy i powyższy wyjątek nie ma zastosowania.

Zarówno trzeci, jak i czwarty test nie używają wyszukiwania operatora, ale zwykle niewykwalifikowanego wyszukiwania.Zwykle niewykwalifikowany odnośnik znajduje ::operator~(const Target&) (w przypadkach 1 i 3) i anotherFunction (w przypadku 4).

+1

Wydaje się, że jest to decyzja przed standaryzacją: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1137.asc Nie jestem pewien co do racjonalnego uzasadnienia. – dyp

+0

Interesujące. To prawdopodobnie wyjaśnia również, dlaczego kompiluje się na 'gcc 4.7.3'. IIRC, implementacja 'enum class' w GCC w tym czasie była oparta na' struct's – Clivest

Powiązane problemy