#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);
}
Оба лязга и G дают неоднозначный оператор преобразования, но Visual Studio компилирует нормально и печатает «оператор Const CL2 &». Как должно быть правильно в соответствии со стандартом?
Как я выяснил, преобразование CL1 в const CL2 & находится в контексте инициализации копирования (как часть прямой инициализации объекта cl2). Я видел n4296 проект, [over.match.copy]:Ссылка связывания через неоднозначный оператор преобразования
Предполагая, что «CV1 T» типа объекта инициализации, с T типа класса, функция кандидатов выбираются следующим образом:
- Преобразовательные конструкторы (12.3.1) of T являются кандидатами функций.
- Если тип выражения инициализатора является классом типа «cv S», рассматриваются неявные функции преобразования S и его базовые классы . При инициализации временного привязки к первому параметру конструктора, где параметр имеет тип «ссылка на возможный Tv-квалифицированный T», а конструктор называется с единственным аргументом в контексте прямой инициализации объект типа «cv2 T», явные функции преобразования также относятся к . Те, которые не скрыты внутри S, и дают тип, для которого cv-неквалифицированная версия является тем же типом, что и T или является производным классом , являются функциями-кандидатами. Функции преобразования, которые возвращают значения «ссылки на X» или значения x в зависимости от типа ссылки типа X и поэтому считаются выходными для X процесс выбора функций-кандидатов.
I.e. оба оператора преобразования рассматриваются как возврат CL2 и const CL2 (а не только CL2 без const), и остается решить, какое преобразование лучше: CL2 -> const CL2 & или const CL2 -> const CL2 &. Второй случай кажется более подходящим. Должна ли лучшая конверсия квалификации рассматриваться в этом контексте? Или оба случая - это преобразование идентичности? Я не мог найти его в стандарте
Похоже, Visual Studio * делает * компилирует ваш код. Но * IntelliSense * жалуется на объявление второго объекта. Насколько я понимаю, ваша проблема не в том, что вы думаете. Компилятор не знает, какую функцию оператора преобразования вызывать, поскольку вы не можете перегружать на основе типа возврата, но вы можете перегружать его на основе константы функции. Попробуйте 'operator const CL2 &() const {cout <<" operator const CL2 & "; return cl2; } ' – DeiDei