1

与此 相关问题。通过跟踪slt_pair. hand move. h,似乎ClangG++之间的区别在于内部。我试图模拟对象的分配(pair.first)与实现相同,输出与Clangstd_pair.h输出相同,它是合理的输出,但是为什么在使用对时它会发生变化。

#include <iostream>

struct Foo {
  Foo() {
    std::cout << "default" << std::endl;
  }
  Foo(Foo& f2) {
    std::cout << "non-const" << std::endl;
  }
  Foo(const Foo& f2) {
    std::cout << "const" << std::endl;
  }
};

// static_cast Foo lvalue to rvalue
Foo cast1(Foo foo){

    return static_cast<Foo&&>(foo);
}

// same : check weather foo and Foo are the same type
Foo cast2(Foo foo){
     return static_cast<typename std::remove_reference<Foo>::type&&>(foo);
}

int main() {

        Foo T1; // pair Foo object

        std::cout<<"Start"<<std::endl;
        std::cout<<std::endl;
        

        // (&&) rvalue casting
        T1 = cast2(Foo()); // First pair object

        std::cout << std::endl;

        Foo const foo = T1;// Second pair object

}

Clang如何处理转换lvalue以及rvalue这些不同输出的真正原因。


任何意见都非常感谢,谢谢。

更新:我在接受的评论部分得到了令人满意的答案。

4

1 回答 1

1

我认为并非您示例中的所有内容都按照您的想法进行。return 中的static_castthe 没有意义,cast1and的结果cast2将自动成为右值,因为您按值返回。此外,cast1cast2在内部也是相同的,因为std::remove_reference_t<Foo>Foo。如果你有一些模板,你会需要remove_reference

此外,您将作业与结构混合在一起。在T1 = cast2(Foo());以下情况发生:

  1. 一个未命名的临时由 构造Foo()。这输出default
  2. 这个临时值被复制到 的foo参数中cast2。这输出const,因为我们尝试Foo从临时构造一个对象,并且只有const Foo&, notFoo&可以绑定到临时。
  3. static_cast几乎什么都不做。
  4. foo被退回。通过返回值优化,不调用应该调用的构造函数。
  5. 我们使用默认(和隐式)赋值运算符来分配返回值T1.operator=(const Foo&)。没有任何东西被打印出来。

Foo const foo = T1你调用一个构造函数。由于T1是左值,您将调用构造函数Foo(Foo&)non-const打印。

于 2020-06-01T09:13:14.343 回答