оператор T () не используется в присваивании

Я немного смущен этим. Допустим, у меня есть вспомогательный класс Data

class Data
{
public:
Data(const QVariant &value) : m_Variant(value) { }
operator QString() const { return m_Variant.toString(); }

private:
QVariant m_Variant;
};

тогда, когда я делаю это:

Data d("text");
QString str = d; //str becomes "text"

это работает, но когда я продолжаю делать:

Data d2("text2");
str = d2; //does not compile

он не жалуется:

ambiguous overload for 'operator=' (operand types are 'QString' and 'Data')
candidates are:
...
QString &operator=(const QString &);
QString &operator=(QString &&);
QString &operator=(const char*); <near match>
no known conversion from Data to const char*
QString &operator=(char);

Но даже предоставляя

operator const char*() const;

не помогает. Сообщение о конвертации просто исчезает, а ошибка остается прежней. Есть ли способ решить эту проблему, кроме добавления

QString &operator=(const Data &data);

в QString или явно

str = QString(d2);

?

Я в замешательстве, потому что компилятор четко сделал вывод, что левый операнд является QString и, по-видимому, пытается вызвать преобразование из Data на что бы один из QString«s operator=s принимают, но даже если такое преобразование определено, оно все равно не работает.

РЕДАКТИРОВАТЬ:
Проблема, кажется, исходит из нескольких определений разных operator T() члены. В этом случае operator int(),

5

Решение

У меня нет доступа к онлайн-компилятору с библиотеками Qt, но вот что я собрал из публичной документации QString а также QVariant:

#include <iostream>

struct QString
{
QString() = default;
QString(QString const&) { std::cout << __PRETTY_FUNCTION__ << '\n'; }
QString &operator=(const QString &) { std::cout << __PRETTY_FUNCTION__ << '\n'; return *this; }

QString(char const*)  { std::cout << __PRETTY_FUNCTION__ << '\n'; }
QString &operator=(const char*) { std::cout << __PRETTY_FUNCTION__ << '\n'; return *this; }

QString(char)  { std::cout << __PRETTY_FUNCTION__ << '\n'; }
QString &operator=(char) { std::cout << __PRETTY_FUNCTION__ << '\n'; return *this; }
};

struct QVariant
{
QVariant(QString const&) { std::cout << __PRETTY_FUNCTION__ << '\n'; }
QVariant(char const*)  { std::cout << __PRETTY_FUNCTION__ << '\n'; }
};

struct Data
{
Data(QVariant const&) { std::cout << __PRETTY_FUNCTION__ << '\n'; }
operator QString() const  { std::cout << __PRETTY_FUNCTION__ << '\n'; return QString(); }
operator int() const { std::cout << __PRETTY_FUNCTION__ << '\n'; return QString(); }
};

int main()
{
Data d("text");
QString str = d;

Data d2("text2");
str = d2;
}

Живой пример

Прямая-инициализация из d("text") а также d2("text2"), перерабатывать char const* -> QVariant через конструкторы

QVariant::QVariant(const char*)
Data::Data(const QVariant&)

копия инициализация QString str = d elides призыв к QString скопировать конструктор на временный QString объект производится

Data::operator QString() const

Теперь об ошибке: назначение из str = d2 пытается сопоставить различные операторы присваивания QString::operator= перегрузки к вашему Data аргумент. однажды Data имеет несколько операторов преобразования (для QString и к int например, вы получите неоднозначность разрешения перегрузки, потому что QString имеет как регулярное назначение operator=(QString) так же хорошо как operator=(char) (который может занять int).

TL; DR есть только один маршрут для строительства: char const* -> QVariant -> Data, Но есть два маршрута Data -> QString а также Data -> int -> char что приводит к действительному аргументу для оператора присваивания.

Исправить: использовать explicit преобразование операторов в ваш собственный код (или удаление одного или нескольких из них).

6

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector