Clang vs G ++左值到右值转换 [英] Clang vs G++ lvalue to rvalue conversion

查看:133
本文介绍了Clang vs G ++左值到右值转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与此问题一个相关的问题。通过跟踪 slt_pair。 h 移动。 h ,看来 Clang G ++ 之间的区别是内部的。我尝试模拟对象(pair.first)的分配,与 std_pair.h 的实现相同,输出与 Clang

The question related to this one. By tracing slt_pair. h and move. h, it's seems that the difference between Clang and G++ is internally. I have tried to simulate the assignment of the object (pair.first) as same as the implementation of std_pair.h, the output is same as Clang output it's reasonable output, but why when using pairs it's changes.

#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 的转换,真正的原因是什么这些不同的输出。

How Clang deals with conversion lvalue to rvalue and what the real reason for these different outputs.

感谢任何意见。

更新 :在接受的注释部分中,我得到了令人满意的答复。

Update: I have got a satisfying answers on the comments section of the accepted one.

推荐答案

我认为您示例中的所有内容都不能做什么你认为是的。返回中的 static_cast 是没有意义的, cast1 cast2 将自动为右值,因为您按值返回。此外, cast1 cast2 在内部也是相同的,因为 std :: remove_reference_t< Foo> 只是 Foo 。如果您有进行模板工作,则需要 remove_reference

I think not everything in your example does what you think it does. The static_cast in the returns is meaningless, the result of cast1 and cast2 will automatically be an rvalue since you return by value. Further, cast1 and cast2 are also internally identical since std::remove_reference_t<Foo> is just Foo. You would need remove_reference if you had some templating going on.

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

Furthermore, you are mixing assignments with constructions. In T1 = cast2(Foo()); the following happens:


  1. A未命名的临时文件由 Foo()构造。这将输出 default

  2. 该临时变量被复制到 foo 参数code> cast2 。这会输出 const ,因为我们试图从一个临时对象构造一个 Foo 对象,并且仅 const Foo& ,而不是 Foo& ,可以绑定到临时文件。

  3. static_cast 几乎没有任何作用。

  4. foo 被返回。通过返回值优化,不应调用应调用的构造函数。

  5. 我们使用默认(和隐式)赋值运算符 T1.operator =(const Foo&)来分配返回值。

  1. A unnamed temporary is constructed by Foo(). This outputs default
  2. This temporary is copied to the foo argument of cast2. This outputs const, since we try to construct a Foo object from a temporary, and only const Foo&, not Foo&, can bind to a temporary.
  3. The static_cast does pretty much nothing.
  4. foo is returned. By return value optimization, the constructor that should be called, is not called.
  5. We assign the returned value by using the default (and implicit) assignment operator T1.operator=(const Foo&). Nothing gets printed.

Foo const foo = T1 中,您称为构造函数。由于 T1 是左值,因此您将调用构造函数 Foo(Foo&) non -const 已打印。

In Foo const foo = T1 you call a constructor. Since T1 is an lvalue, you will call the constructor Foo(Foo&) and non-const is printed.

这篇关于Clang vs G ++左值到右值转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆