具有xvalue操作数的三元运算符

6

假设我们有一个包含两个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"的xvalue;输出应该与"std::move(a).foo();"相同。 - M.M
根据这个答案,应该是A&&.foo() - M.M
2
是的,clang 是正确的。MSVC 错误地进行了复制。我已经在 gcc 的 bug 报告中发布了此问题:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88103 - Oliv
1
这里有一个有点相关的问题,链接在此:https://dev59.com/Hq_la4cB1Zd3GeqPzNlq,在那里gcc也出现了错误。 - Shafik Yaghmour
1个回答

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接