【问题标题】:What's the value of rvalues? [duplicate]右值的价值是什么? [复制]
【发布时间】:2015-08-18 03:38:15
【问题描述】:

也就是说,当一个人利用 C++11 类型名 && 特性(如移动构造函数等)时,通常会在设计良好的 C++03 代码中获得多少性能改进?多久值得一次麻烦,在什么情况下?

编辑:

想象一个替代宇宙,其中使用关键字“returning”而不是右值引用 C++11 扩展 C++03,该关键字标记将由函数返回的局部变量。如果局部变量被标记为“返回”,则它被放置在返回值通常所在的堆栈部分中。想象一下,您可以像这样使用该关键字:

SomeClass foo()
{
    returning SomeClass bar; // Created where return value usually resides.
    // do something with bar
    return bar; // No copy constructor is involved here.
}

我认为这种机制可以创建 make_unique 和右值引用一样,并且会减少混乱和潜在的陷阱。三规则将保持三规则,而不是变成五规则;不会混淆 && if rvalue ref 或universal ref;不需要 std::move 等。

我在这里错过了什么?

【问题讨论】:

  • 您很快就被评为“过于宽泛”,但我认为这不应该阻止您的调查。也许选择几个重点案例并询问一些非常具体的问题?
  • 测量。 Measure。测量。
  • 这并不是说它使事情表现得更好,而是它使避免不必要的分配/复制/释放周期变得更加简洁和容易,从而(我们希望)产生更清晰的代码,更容易理解和维护。看看人们构建的一些 C++11 之前的怪物,以获得移动语义自然给你的东西。例如,比较auto_ptrunique_ptr
  • 右值引用的值是你设置的值,当然使用赋值运算符。
  • 您在编辑中建议的替代宇宙被称为 RVO,并且已经被大多数体面的编译器实现。

标签: c++ c++11 language-lawyer move-semantics rvalue-reference


【解决方案1】:

右值引用的价值并不主要在于性能。更确切地说,它在于表现力。如果没有右值引用,您就无法在类型系统中以有用的方式对所有权进行编码。由于右值引用允许的所有权转移,我们现在可以编写完全正确的子表达式代码,没有非本地依赖。

例如,C++11 之前的:

int * p = new int[N];    // may be a bug, who knows?

                         // ... keep paying attention...

delete p;                // ah, no bug... or is it?

使用右值:

auto p = std::make_unique<int[]>(N);   // fine

请注意,现代示例中没有一个 子表达式 本身就是资源错误的根本原因。相同的方法可以应用于无数资源/句柄对:内存/指针、文件/句柄、互斥体/锁、任务/延续等。

(如果您将资源获取和释放视为两个相反的极点,那么现代 C++ 应该写得像一块磁铁:两者始终作为一个实体的一部分。)

让类型系统完全保证正确性的局部性是对语言的巨大改进。

【讨论】:

  • 照常加一。如果我能负担得起你,我会尝试雇用你!
  • @Bathsheba 为什么要聘请可以免费解决您问题的人? :-)
  • @Kerrek,您能解释一下为什么右值引用对您的示例至关重要吗?我得到了 unique_ptr、shared_ptr 和它们的 make_ 的值;这些确实是对 new/delete 的巨大改进。我不明白为什么右值引用对此至关重要。实际上,给我 2 分钟,我将添加 C++03 的替代(完全虚构)扩展。
  • @Michael:我不太明白。您现在的问题是为什么选择一种语言扩展而不是另一种?我不知道,我不在那儿。您是否将您的设计作为提案提交?只有提议的内容才会被接受。
  • @KerrekSB ,忽略编辑;问题是:为什么右值引用在您的示例中是必不可少的?为什么没有它们就不能实现 make_unique?
猜你喜欢
  • 2020-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-17
  • 2015-12-13
  • 1970-01-01
相关资源
最近更新 更多