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?
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
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