Скажем, у нас есть троичный оператор с двумя операндами 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 правильным на этом? Спасибо!