Разница в выборе const-overload для операторов-членов и не-членов на временной - PullRequest
3 голосов
/ 03 января 2012

При ответе на этот вопрос я натолкнулся на интересную разницу в разрешении перегрузки rvalue для ссылки между операторами-членами и операторами, не являющимися членами.

С учетом двух операторов, не являющихся членами, один передавая левый параметр как const, а другой как неконстантный, GCC 4.4.3 и MSVC2010 выбирают версию const при вызове с r-значением.

Однако, учитывая два оператора-члена, один const и один неконстантный, оба компилятора выбирают неконстантную версию.

Я предполагаю, что оба компилятора соответствуют этому стандарту, поэтому мне любопытно, почему существует такое расхождение между разрешением перегрузки const между членами и нечленами. Пожалуйста, просветите меня:)

Вот код, иллюстрирующий разницу:

#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;
}

1 Ответ

2 голосов
/ 03 января 2012

R-значения не могут быть привязаны к ссылкам на nonconst, поэтому допустима только перегрузка ссылки на const свободной функции: operator<<(C(5), 6);.

Это не относится к оператору-члену, который является просто C(5).operator<<(6), а объект C не является аргументом функции. Вам нужно будет сказать static_cast<const C &>(C(5)) << 6, чтобы получить там константную версию, поскольку именно константа this отличает перегрузки двух операторов-членов.

При наличии операторов-членов и операторов свободных функций предпочтительна функция-член, поэтому объединение всего этого объясняет наблюдаемое поведение.

...