运算符 T() 未在赋值中使用

operator T() not used in assignment

我对此有点困惑。假设我有一个帮手 class 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 并且它显然试图调用从 DataQString 之一的转换的 operator=s 接受但即使定义了这种转换它仍然不起作用。

编辑: 问题似乎来自不同 operator T() 成员的多个定义。在这种情况下 operator int().

我无法访问带有 Qt 库的在线编译器,但这是我从 QStringQVariant 的 public 文档中拼凑的内容:

#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;
}

Live Example

d("text")d2("text2")直接初始化,通过构造函数

转换char const* -> QVariant
QVariant::QVariant(const char*)
Data::Data(const QVariant&)

复制初始化 QString str = d 省略了对 QString 临时 QString 对象上的复制构造函数的调用

Data::operator QString() const

现在是错误:str = d2 赋值 试图将各种赋值运算符 QString::operator= 重载与您的 Data 参数相匹配。一旦 Data 有多个转换运算符(例如 QStringint),您将得到重载解析歧义,因为 QString 具有常规赋值 operator=(QString)以及 operator=(char)(可以使用 int)。

TL;DR只有一条施工路线:char const* -> QVariant -> Data。但是有两条路线 Data -> QStringData -> int -> char 导致赋值运算符的有效参数。

修复:在您自己的代码中使用 explicit 转换运算符(或删除其中一个或多个)。