运算符 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
并且它显然试图调用从 Data
到 QString
之一的转换的 operator=
s 接受但即使定义了这种转换它仍然不起作用。
编辑:
问题似乎来自不同 operator T()
成员的多个定义。在这种情况下 operator int()
.
我无法访问带有 Qt 库的在线编译器,但这是我从 QString
和 QVariant
的 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;
}
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
转换运算符(或删除其中一个或多个)。
我对此有点困惑。假设我有一个帮手 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
并且它显然试图调用从 Data
到 QString
之一的转换的 operator=
s 接受但即使定义了这种转换它仍然不起作用。
编辑:
问题似乎来自不同 operator T()
成员的多个定义。在这种情况下 operator int()
.
我无法访问带有 Qt 库的在线编译器,但这是我从 QString
和 QVariant
的 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;
}
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
转换运算符(或删除其中一个或多个)。