简体   繁体   中英

Difference in choice of const-overload for member and non-member operators on temporary

While answering this question I came across an interesting difference in the overload resolution of rvalue to reference between member and non-member operators.

Given two non-member operators, one passing the left parameter as const and one as non-const, both GCC 4.4.3 and MSVC2010 choose the const version when called with an rvalue.

However, given two member operators, one const and one non-const, both compilers choose the non-const version.

I assume that both compilers are complying with the standard on this, so I am curious as to why there is this discrepancy between const overload resolution between members and non-members. Please enlighten me :)

Here's some code to illustrate the difference:

#include <iostream>

class C {
public:
    C(int i) { }

    /*
    C operator<<(C const &rhs) {
        std::cout << "member non-const" << std::endl;
        return *this;
    }
    C operator<<(C const &rhs) const {
        std::cout << "member const" << std::endl;
        return *this;
    }
    //*/
};

C operator<<(C &lhs, C const &rhs) {
    std::cout << "non-member non-const" << std::endl;
    return lhs;
}
C operator<<(C const &lhs, C const &rhs) {
    std::cout << "non-member const" << std::endl;
    return lhs;
}

int main() {
    // Will print:
    // "non-member const" when member operators are commented out
    // "member non-const" when members are uncommented
    C(5) << 6;
}

Rvalues cannot bind to references-to-nonconst, so only the reference-to-const overload of the free function is viable: operator<<(C(5), 6); .

This does not apply to the member-operator, which is simply C(5).operator<<(6) , and the C -object isn't a function argument. You would have to say static_cast<const C &>(C(5)) << 6 to get the const version there, since it is the constness of this that distinguishes the two member operator overloads.

In the presence of both member and free-function operators, the member function is preferred, so putting all this together explains the observed behaviour.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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