Тернарный оператор с операндами xvalue - PullRequest
0 голосов
/ 19 ноября 2018

Скажем, у нас есть троичный оператор с двумя операндами xvalue.

struct A {
    A() { std::cout<<"A ctor"<<std::endl; }
    ~A() { std::cout<<"A dtor"<<std::endl; }
    A(A const&) { std::cout<<"A copy ctor"<<std::endl; }
    A(A&&) { std::cout<<"A move ctor"<<std::endl; }

    void foo() & { std::cout<<"A&.foo()"<<std::endl; }
    void foo() const& { std::cout<<"A const&.foo()"<<std::endl; }
    void foo() && { std::cout<<"A&&.foo()"<<std::endl; }
    void foo() const&& { std::cout<<"A const&&.foo()"<<std::endl; }
};

int main()
{
    A a;
    A a2;
    (true? static_cast<A&&>(a) : static_cast<A&&>(a2)).foo();
    return 0;
}

Согласно условному оператору cppreference

4) Если E2 и E3 являются glvalues ​​одного типа и того же значения категория, то результат имеет тот же тип и категорию значения, и битовое поле, если хотя бы одно из E2 и E3 является битовым полем.

Результатом должен быть также A &&, и конструкторы копирования или перемещения не ожидаются. Я прав?

Но gcc, clang и Visual Studio дают разные результаты по этому вопросу.

gcc: A&.foo()

лязг: A&&.foo()

VS:

A move ctor
A&&.foo()

Если мы приведем оба типа операндов к A const&&, gcc будет A const&.foo(), clang будет A const&&.foo(), VS будет A const&&.foo() с вызванным копированием ctor.

Является ли Clang правильным на этом? Спасибо!

...