【问题标题】:C++ priority of compare operator overload vs conversion operator比较运算符重载与转换运算符的 C++ 优先级
【发布时间】:2015-02-05 07:51:13
【问题描述】:

考虑以下程序:

#include <iostream>

using namespace std;

class Foo {
public:
    int k;

    operator int() {
        cout << "convert int" << endl;
        return k;
    }

#if USE_COMPARE
    bool operator < (int rhs) {
        cout << "compare with" << endl;
        return (k < rhs);
    }
#endif
};

int main()
{
    Foo f;
    f.k = 3;
    int m = 5;


    if (f < m) {
        cout << 1 << endl;
        return 1;
    }
    cout << 0 << endl;
    return 0;
}

当定义USE_COMPARE 时,if (f&lt;m) 的比较将使用比较运算符重载。如果没有定义USE_COMPARE,它会将fFoo转换为int,然后进行整数比较。在我看来,比较运算符重载的优先级高于转换运算符。任何人都可以从 C++ 标准的角度确认这一点吗?

但我认为比较运算符应该优先考虑是很自然的。但请从C++标准的角度回答问题。

谢谢。

【问题讨论】:

    标签: c++ operator-overloading operator-precedence


    【解决方案1】:

    13.3.3.2/2

    在比较隐式转换序列的基本形式时(如 在 13.3.3.1 中定义)

    标准转换序列 (13.3.3.1.1) 是更好的转换 序列而不是用户定义的转换序列或省略号 转换顺序,以及

    用户定义的转换序列 (13.3.3.1.2) 是更好的转换 序列比省略号转换序列 (13.3.3.1.3)。

    13.3.3.1/3

    格式良好的隐式转换序列是以下之一 形式:——标准转换序列(13.3.3.1.1),

    — 用户定义的转换序列 (13.3.3.1.2),或

    ——省略号转换序列 (13.3.3.1.3)。

    13.3.3.1/8

    如果不需要转换即可将参数与参数匹配 类型,隐式转换序列为标准转换 由身份转换(13.3.3.1.1)组成的序列。

    13.3.3.1.2/1

    用户定义的转换序列由初始标准组成 转换序列后跟用户定义的转换 (12.3) 其次是第二个标准转换序列。如果用户定义 转换由转换函数 (12.3.2) 指定,初始 标准转换序列将源类型转换为隐式 转换函数的对象参数。

    如果定义了比较运算符,编译器有两种变体:

    1) 让

    IF = Identity(f)
    

    呼叫:

    IF.operator <(int)
    

    2) 让:

    IF = Identity(f);
    converted_int = Identity(IF.operator int());
    

    呼叫:

    operator < (converted_int, int);
    

    隐式转换序列优于用户转换序列。 标准中有两个关于引号重载解决方案的词,如果您愿意,可以阅读 par 13.3,或者只是 13.3.3[over.best.ics]。

    【讨论】:

    • 但在我看来,我明确定义了&lt; 运算符重载,因此应该使用&lt; 运算符重载,因为它不需要转换,对吧?
    • @Robin Hsu,这实际上是写在答案中的。
    • 您似乎说存在两个差异,这意味着两者都是合法的,有些编译器这样做而其他编译器这样做?或者你能解释更多并原谅我英语不好......(或糟糕的 C++ :-))
    • @RobinHsu 编译器实际上有两个变体。但是应该首先选择标准(仅身份转换)。
    • 你的意思是,按照标准,应该只有一个选择,但实际上,有些编译器选择不遵循标准,对吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 2017-07-27
    相关资源
    最近更新 更多