简体   繁体   English

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

[英]operator T() not used in assignment

I am a bit confused by this. 我有点困惑。 Lets assume I have a helper class Data 让我们假设我有一个帮助类Data

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

private:
    QVariant m_Variant;
};

then when I do this: 那时当我这样做:

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

it works but when I continue to do: 它有效,但当我继续做:

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

it fails complaining: 抱怨失败:

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);

But even providing 但即使提供

operator const char*() const;

does not help. 没有帮助。 The message about conversion just disappears and the error remains the same. 关于转换的消息刚刚消失,错误保持不变。 Is there a way to solve this other than adding 除了添加之外,有没有办法解决这个问题

QString &operator=(const Data &data);

to QString or calling explicitly QString或显式调用

str = QString(d2);

?

I am confused because the compiler clearly deduced correctly that the left operand is a QString and it is apparently trying to call conversion from Data to what would one of the QString 's operator= s accept but even if such conversion is defined it still does not work. 我很困惑,因为编译器清楚地推断出左操作数是一个QString ,它显然试图调用从Data转换为QString的一个operator=接受的内容,但即使定义了这样的转换,它仍然没有工作。

EDIT: The problem seems to come from multiple definitions of different operator T() members. 编辑:问题似乎来自不同operator T()成员的多个定义。 In this case operator int() . 在这种情况下, operator int()

I haven't got access to an online compiler with the Qt libraries, but here's what I pieced together from the public documentation of QString and QVariant : 我没有访问带有Qt库的在线编译器,但这是我从QStringQVariant的公共文档拼凑而成的内容:

#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 实例

The direct-initializations of d("text") and d2("text2") , convert char const* -> QVariant through the constructors d("text")d2("text2")直接初始化 ,通过构造char const* -> QVariant转换char const* -> QVariant

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

The copy-initialization QString str = d elides a call to the QString copy constructor on a temporary QString object produced by 复制初始化 QString str = d省略对由生成的临时QString对象的QString复制构造函数的调用

Data::operator QString() const

Now for the bug: the assignment of str = d2 tries to match the various assignment operators QString::operator= overloads to your Data argument. 现在为bug: str = d2赋值尝试将各种赋值运算符QString::operator= overloads与Data参数匹配。 Once Data has multiple conversion operators (to QString and to int eg), you will get an overload resolution ambiguity because QString has both the regular assignment operator=(QString) as well as the operator=(char) (which can take int ). 一旦Data有多个转换运算符(到QStringint例如),你将得到一个重载QString歧义,因为QString既有常规赋值operator=(QString)又有operator=(char) (可以取int )。

TL;DR there is only one route for construction: char const* -> QVariant -> Data . TL; DR只有一条构造路径: char const* -> QVariant -> Data But there are two routes Data -> QString and Data -> int -> char that lead to a valid argument for the assignment operator. 但是有两个路由Data -> QStringData -> int -> char ,它们导致赋值运算符的有效参数。

Fix: use explicit conversion operators in your own code (or remove one or more of them). 修复:在您自己的代码中使用explicit转换运算符(或删除其中的一个或多个)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM