【问题标题】:Clang vs G++ lvalue to rvalue conversionClang vs G++ 左值到右值转换
【发布时间】:2020-09-19 12:48:42
【问题描述】:

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

#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 如何处理从 lvaluervalue 的转换以及这些不同输出的真正原因。


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

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

【问题讨论】:

  • “似乎 Clang 和 G++ 之间的区别在于内部” 链接的问答似乎说区别在于 std::pair 实现,而不是编译器行为。 “输出与 Clang 相同” “这些不同输出的真正原因是什么” 你得到 GCC 和 Clang 的相同输出还是不同的输出?如果相同,那么问题到底是什么?
  • @HolyBlackCat,我提到的另一个问题是使用对,在这种情况下,它们给出了不同的结果。使用对而不是这些分配时的区别。

标签: c++ g++ clang llvm lvalue-to-rvalue


【解决方案1】:

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

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

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

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

【讨论】:

  • 我注意到了,但我也尽量保持与移动相同。 h 因为我不明白为什么 g++ 在直接成对的情况下会产生不同的输出。
  • 赋值我明白一切都不负责任,因为复制构造函数错误和赋值我只是模拟使用pair时发生的事情
  • 对不起,我不明白你的意思。我很确定您上面的代码与两对实现的差异无关。如果您能指出您查看不同配对代码的位置,我可以看看并尝试解释它们的不同之处。
  • libstdc++(Linux 上 gcc 和 clang 的默认值)和 libc++(macOS 上 clang 的默认值)
  • 附录:libc++ 在utility 中有对,而libstdc++ 在stl_pair.h 中有它
猜你喜欢
  • 2017-11-24
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
  • 2017-08-18
  • 1970-01-01
相关资源
最近更新 更多