Han*_*Han 7 c++ c++11 c++14 c++17 value-categories
假设我们有一个带有 2 个 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;
}
Run Code Online (Sandbox Code Playgroud)
根据cppreference条件运算符
4) 如果 E2 和 E3 是相同类型和相同值类别的左值,则结果具有相同类型和值类别,并且如果 E2 和 E3 至少其中之一是位字段,则结果是位字段。
结果也应该是 A&& 并且不需要复制或移动构造函数。我对么?
但 gcc、clang 和 Visual Studio 对此给出了不同的结果。
海湾合作委员会:A&.foo()
铛:A&&.foo()
对比:
A move ctor
A&&.foo()
Run Code Online (Sandbox Code Playgroud)
如果我们将两种操作数类型都转换为A const&&
,gcc 将为A const&.foo()
,clang 将为A const&&.foo()
,VS 将带有A const&&.foo()
一个名为的复制构造函数。
clang 是正确的吗?谢谢!
是的,程序执行的正确输出是:
A ctor
A ctor
A&&.foo()
A dtor
A dtor
Run Code Online (Sandbox Code Playgroud)
相应的 GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88103已在 GCC 7.5、8.3、9.1 版本中修复。演示: https: //gcc.godbolt.org/z/6hbaW4W5q
最新的 MSVC 还可以打印正确的输出。