假设我们有一个包含两个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条件运算符,如果E2和E3是相同类型和相同值类别的glvalue,则结果具有相同的类型和值类别,并且如果E2和E3中至少一个是位域,则为位域。结果应该也是A&&,不需要复制或移动构造函数。我理解得没错吧?
但是gcc、clang和Visual Studio在此方面给出了不同的结果。
gcc:
A&.foo()
clang: A&&.foo()
VS:A move ctor
A&&.foo()
如果我们将两个操作数类型都转换为
A const&&
,gcc会是A const&.foo()
,clang会是A const&&.foo()
,VS会是A const&&.foo()
并调用复制构造函数。在此问题中,clang是正确的吗?谢谢!
A&&.foo()
。 - M.M