我对此感到有点困惑。让我们假设我有一个帮助类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
&#之一39; s operator=
接受,但即使定义了这种转换,它仍然不起作用。
修改
问题似乎来自不同operator T()
成员的多个定义。在这种情况下operator int()
。
答案 0 :(得分:6)
我无法访问带有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;
}
<强> 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
有多个转换运算符(例如QString
和int
),您将获得重载决策歧义,因为QString
具有常规赋值operator=(QString)
以及operator=(char)
(可以int
)。
TL; DR 只有一条施工路线:char const* -> QVariant -> Data
。但是有两条路由Data -> QString
和Data -> int -> char
导致赋值运算符的有效参数。
修复:在您自己的代码中使用explicit
转化运算符(或删除其中一个或多个)。