#include <iostream>
using namespace std;
struct CL2
{
CL2(){}
CL2(const CL2&){}
};
CL2 cl2;
struct CL1
{
CL1(){}
operator CL2&(){cout<<"operator CL2&"; return cl2;}
operator const CL2&(){cout<<"operator const CL2&"; return cl2;}
};
CL1 cl1;
int main()
{
CL1 cl1;
CL2 cl2 (cl1);
}
Zarówno dzyń i gcc dają niejednoznaczne operatora konwersji, ale Visual Studio kompiluje ok i drukuje "const operator CL2 &". Jak musi być zgodna z normą?
Tak jak nieoczekiwanie, konwersja CL1 do const CL2 & odbywa się w kontekście inicjowania kopii (jako część bezpośredniej inicjalizacji obiektu cl2). Ja widać n4296 projekt [over.match.copy]odniesienia wiązania poprzez niejednoznaczną operatora konwersji
Zakładając, że „CV1 T” jest typ obiektu zainicjowany z T typu klasy funkcje kandydujące są wybrane jako:
- Konwertujące konstruktory (12.3.1) z T są kandydatami funkcji .
- Kiedy typem wyrażenia inicjalizującego jest klasa "cv S", rozważane są nie-jawne funkcje konwersji S i jej klas podstawowych . Podczas inicjowania tymczasowego, który ma zostać powiązany, do pierwszego parametru konstruktora, którego parametrem jest typ "odniesienie do potencjalnie kwalifikowanego cv T", a konstruktor jest nazywany z pojedynczym argumentem w kontekście bezpośredniej inicjalizacji obiekt typu "cv2 T", jawne funkcje konwersji są również rozważane jako . Te, które nie są ukryte w S i dają typ, którego nienaalikowana wersja cv jest tego samego typu co T lub jest pochodną klasy , są kandydatami. Funkcje konwersji, które zwracają "odniesienie do X" zwracanych wartości lub x wartości, w zależności od typu odniesienia , typu X, a zatem są uważane za zapewniające X dla tego procesu wyboru kandydatów w ramach procesu .
tj. oba operatory konwersji są uważane za powrót CL2 i const CL2 (nie tylko CL2 bez const) i pozostaje do rozwiązania, która konwersja jest lepsza: CL2 -> const CL2 & lub const CL2 -> const CL2 &. Drugi przypadek wydaje się bardziej odpowiedni. Czy w tym kontekście należy rozważyć lepszą konwersję kwalifikacji? A może oba przypadki to konwersja tożsamości? Nie mogłem znaleźć go w standardzie
Co dziwne Visual Studio * robi * kompiluje twój kod. Ale * IntelliSense * narzeka na zadeklarowanie drugiego obiektu. O ile rozumiem, twój problem nie jest taki, jak ci się wydaje. Kompilator nie wie, którą funkcję operatora konwersji wywołać, ponieważ nie można przeciążać w oparciu o typ powrotu, ale można przeciążać na podstawie stałej funkcji. Wypróbuj 'operator const CL2 &() const {cout <<" operator const CL2 & "; return cl2; } ' – DeiDei