Есть некий класс, в очень упрощенном виде выглядит так:
class variant
{
public:
variant (){};
template
operator string ()
{
string str = "sss";
return str;
}
};
и есть программа:
int main()
{
variant v1;
int x1 = v1; // тут все хорошо (вызывается operator int ())
x1 = v1; // тут тоже все хорошо (вызывается так же operator int ())
variant v2;
string s1 = v2; // тут все хорошо (вызывается operator string ())
s1 = v2; // тут получаю ошибку компиляции
return 0;
}
немогу понять в чем дело, если задаю переменной типа string значение при инициализации то все нормально, но если пытаюсь присвоить переменной типа string значение получаю ошибку(с встроенными типами данных все хорошо):
error: ambiguous overload for 'operator=' (operand types are 'std::__cxx11::string {aka std::__cxx11::basic_string
что я делаю не так? как правильно перегрузить чтото вроде string operator= (variant)?
компилятор: gcc version 5.1.0 (MinGW-W64 project)
Ответ
Всё просто, в строке string s1 = v2; вызывается конструктор копирования std::string, у которого есть только один вариант аргумента: const std::string&. Поэтому происходит преобразование и всё работает.
С другой стороны, строка s1 = v2; вызывает std::string::operator= и тут уже вариантов аргументов куда больше, поэтому компилятор не может определить, в какой тип нужно конвертировать v2. Вылечить это можно только явным преобразованием.
На деле получается, что и с явным преобразованием получается та же ошибка. Дальше будут мои спекуляции почему так происходит, чтобы дать ответ точно — нужно штудировать стандарт.
Итак, строчка s1 = static_cast
С другой стороны, когда мы пытаемся преобразовать к ссылке на std::string, получается, что прямое преобразование побеждает — в непрямом нужно сначала создать std::string и только потом можно будет преобразовать к ссылке, т.е. 2 преобразования, а в первом случае нужно только одно.
Что нам всё это даёт? Даёт нам это понимание, что если написать код, который запретит шаблонному оператору преобразования участвовать в операциях, когда происходит конвертация в std::string, тогда наш код с преобразованием должен заработать:
template
template
operator std::string () const
{
std::string str = "sss";
return str;
}
};
//...
s1 = static_cast
Комментариев нет:
Отправить комментарий