5

Tôi hơi bối rối vì điều này. Cho phép giả sử tôi có một lớp helper DataToán tử T() không được sử dụng trong nhiệm vụ

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

private: 
    QVariant m_Variant; 
}; 

sau đó khi tôi làm điều này:

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

nó hoạt động nhưng khi tôi tiếp tục làm:

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

nó vẫn thất bại phàn nàn:

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

Nhưng thậm chí cung cấp

operator const char*() const; 

không giúp ích gì. Thông báo về chuyển đổi chỉ biến mất và lỗi vẫn giữ nguyên. Có cách nào để giải quyết này khác vì thêm

QString &operator=(const Data &data); 

để QString hoặc gọi một cách rõ ràng

str = QString(d2); 

?

Tôi đang bối rối bởi vì trình biên dịch suy luận rõ ràng một cách chính xác rằng toán hạng bên trái là một QString và nó dường như đang cố gắng gọi chuyển đổi từ Data những gì sẽ là một trong những QString 's operator= s chấp nhận nhưng ngay cả khi chuyển đổi như vậy được định nghĩa nó Vẫn không làm việc.

CHỈNH SỬA: Sự cố có vẻ đến từ nhiều định nghĩa khác nhau của các thành viên operator T() khác nhau. Trong trường hợp này là operator int().

+2

bài tập "đúng" đầu tiên, không nên là 'QString str = d;' thay vì 'QString str = Data;'? – Gombat

+0

'Dữ liệu' là gì? Bạn có thể cung cấp mã tối thiểu cho lớp này không? – Gombat

+0

@Gombat Đã sửa lỗi đánh máy và cung cấp bộ xương Dữ liệu. Trong ứng dụng của tôi dữ liệu không phải là một QVariant nhưng thực sự là một giá trị rapidjson nhưng đối với các sự đơn giản, tôi đã sử dụng QVariant trong ví dụ. – Resurrection

Trả lời

6

tôi đã không nhận được quyền truy cập vào một trình biên dịch trực tuyến với các thư viện Qt, nhưng đây là những gì tôi chắp ghép từ các tài liệu công khai của 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

Các các lần khởi tạo trực tiếp của d("text")d2("text2"), chuyển đổi char const* -> QVariant thông qua các hàm tạo

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

Các sao chép khởiQString str = d elides một lời kêu gọi các nhà xây dựng QString bản sao trên một đối tượng tạm thời QString sản xuất bởi

Data::operator QString() const 

Bây giờ cho các lỗi: sự phân công của str = d2 cố gắng để phù hợp với các toán tử gán khác nhau QString::operator= quá tải đối số Data của bạn. Khi Data có nhiều toán tử chuyển đổi (đến QString và đến int ví dụ:), bạn sẽ nhận được sự mơ hồ về độ phân giải quá tải vì QString có cả nhiệm vụ thường xuyên operator=(QString) cũng như operator=(char) (có thể mất int).

TL; DR chỉ có một tuyến đường để xây dựng: char const* -> QVariant -> Data. Nhưng có hai tuyến đường Data -> QStringData -> int -> char dẫn đến một đối số hợp lệ cho toán tử gán.

Khắc phục: sử dụng explicit toán tử chuyển đổi trong mã của riêng bạn (hoặc xóa một hoặc nhiều người trong số họ).

+0

Giải thích đầy đủ về vấn đề ở đây là gì. Tôi sẽ thêm rằng cho các giải pháp xem bình luận cuối cùng bởi @dyp cho OP. – Resurrection

+0

@Resurrection cảm ơn, cập nhật! – TemplateRex

Các vấn đề liên quan