C++ 叮当声vs G++;左值到右值的转换

C++ 叮当声vs G++;左值到右值的转换,c++,g++,clang,llvm,lvalue-to-rvalue,C++,G++,Clang,Llvm,Lvalue To Rvalue,这个问题与此相关。通过跟踪slt\u对。h和移动。h,似乎Clang和G++之间的区别是内在的。我尝试模拟对象(pair.first)的赋值,与std_pair.h的实现相同,输出与Clang输出相同,这是合理的输出,但为什么在使用pair时会发生变化 #include <iostream> struct Foo { Foo() { std::cout << "default" << std::endl; } Foo(

这个问题与此相关。通过跟踪
slt\u对。h
移动。h
,似乎ClangG++之间的区别是内在的。我尝试模拟对象(pair.first)的赋值,与
std_pair.h
的实现相同,输出与Clang输出相同,这是合理的输出,但为什么在使用pair时会发生变化

#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

}
#包括
结构Foo{
Foo(){

std::cout我认为您的示例中并非所有内容都像您认为的那样。返回中的
static\u cast
没有意义,因为您按值返回,
cast1
cast2
的结果将自动为右值。此外,
cast1
cast2
在内部也是相同的,因为
std::remove_reference_t
只是
Foo
。如果要进行一些模板化,则需要
remove_reference

此外,您将赋值与构造混合在一起。在
T1=cast2(Foo());
中,会发生以下情况:

  • 未命名的临时文件由
    Foo()
    构造。这将输出
    default
  • 这个临时对象被复制到
    cast2
    foo
    参数。这将输出
    const
    ,因为我们试图从临时对象构造
    foo
    对象,并且只有
    const foo&
    而不是
    foo&
    ,才能绑定到临时对象
  • static\u cast
    几乎什么都不做
  • 返回
    foo
    。通过返回值优化,不调用应调用的构造函数
  • 我们通过使用默认(和隐式)赋值运算符
    T1来赋值。运算符=(const Foo&)
    。不会打印任何内容

  • Foo const Foo=T1
    中调用构造函数。由于
    T1
    是一个左值,因此您将调用构造函数
    Foo(Foo&)
    ,并打印
    非const

    “似乎Clang和G++之间的区别在内部”链接的Q&A似乎说区别在于
    std::pair
    实现,而不是编译器行为。“输出与Clang相同”“这些不同输出的真正原因是什么?”GCC和Clang的输出是相同的还是不同的?如果是相同的,问题到底是什么?@HolyBlackCat,我提到的另一个问题是使用对,在这种情况下,它们给出了不同的结果。使用对而不是这些赋值时的差异。我注意到了这一点,但我也尝试将其与move.h保持一致I’我不明白为什么g++会在成对的情况下直接产生不同的输出。赋值我知道一切都是不可响应的,因为复制构造函数错误和赋值我只是在模拟使用pairI时发生了什么对不起,但我不明白你的意思。我很确定你上面的代码与d无关o这两个pair实现的不同之处。如果您能告诉我您在哪里看到了不同的pair代码,我可以看一看并尝试解释它们的不同之处。(linux上默认为gcc和clang)和(macOS上默认为clang)附录:libc++有pair in,而libstdc++有pair in