C++ 关于C++; std::vector func(int num){ std::vec; 整数和=0; for(int i=0;i

C++ 关于C++; std::vector func(int num){ std::vec; 整数和=0; for(int i=0;i,c++,c++11,c++14,C++,C++11,C++14,下面关于使用右值和左值引用的代码之间有什么区别 std::vector<std::string> func(int num) { std::vector<std::string> vec; int sum = 0; for(int i = 0; i < num; i++) { sum +=i; std::string s = std::to_string(sum); vec.emplace_back(s); } retur

下面关于使用右值和左值引用的代码之间有什么区别

std::vector<std::string> func(int num) {
  std::vector<std::string> vec;
  int sum = 0;
  for(int i = 0; i < num; i++) {
    sum +=i;
    std::string s = std::to_string(sum);
    vec.emplace_back(s);
  }
  return vec;
}
std::vector res=func(10);//(案例1)
std::vector&&res=func(10);//(案例2)
std::vector&res=func(10);//我犯了个错误!,案例3
常数std::vector&res=func(10);//案例4
问题:

  • 右值引用(案例2)能否保存内存副本?而不是案例1
  • 为什么左值引用(案例3)出现错误,但它与常量
    一起工作(案例4)
  • 当prvalue(“临时”)绑定到右值引用常量左值引用时,临时值的生存期将延长到引用的生存期
  • 常量
    左值引用不会延长prvalue的生存期
  • 右值引用(案例2)能否保存内存副本?而不是案例1

    它保留单个返回对象的生存期。见1

    为什么左值引用(案例3)出现错误

    见第2条

    但是它与const一起工作(案例4)

    见1

  • 右值引用(案例2)能否保存内存副本?而不是案例1
  • 如果您的意思是“案例2是否避免了案例1的某些副本”,那么答案是:否。如果
    res
    是一个自动变量,则两者实际上是相同的。我建议写案例1,因为它更简单,也更容易混淆

    首先,从
    vec
    移动到返回值。实际上,乐观主义者可以忽略这一举措。这种优化称为NRVO(称为返回值优化)

    从C++17开始:在这两种情况下,都是通过上面提到的移动(可能已经省略)直接初始化的

    C++17之前的版本:在这两种情况下,从返回值到初始化对象还有另一个移动。这一举措在实践中也可以省略

  • 为什么左值引用(案例3)出现错误,但它与常量(案例4)一起工作

  • 因为对非常量的左值引用可能不受右值的约束。

    在回答您的问题2时:谢谢您的明确回答!那么右值ref返回类型呢?比如:std::vector&&func(int-num){return std::move(vec);}案例2之间的区别是什么?@eerorika我读了很多遍,但我认为你对“内存拷贝”的理解是正确的。是的,它保存内存中的“副本”。不,它不能保存一个额外的副本到新的内存中。@DrewDormann哦,我想我明白你是如何解释这个问题的了。是的,很不清楚。“than case1”让我相信问题在于case2是否避免了case1所拥有的副本。@Andy rvalue ref返回类型不是prvalue,因此在任何情况下都不会发生生存期延长。这个生命周期延长只适用于prvalues。@DrewDormann很抱歉写得不好,我以前甚至不知道prvalue和xrvalue这两个术语,已经学会了!谢谢你的详细回复!对于c++17,你是说它是完美的,比如说编译器只使用扩展到func之外的函数范围中的内存,没有复制或移动?@Andy如果NRVO是为了摆脱第一步,那么就不会有任何移动。我知道了,非常感谢你的详细回答!
      std::vector<std::string> res = func(10);      // (case 1)
      std::vector<std::string> &&res = func(10);    // (case 2)
      std::vector<std::string> &res = func(10);   // I got an error!, case3
      const std::vector<std::string> &res = func(10);  // case4