相关疑难解决方法(0)

在函数中返回大对象

比较以下两段代码,第一段使用对大对象的引用,第二段使用大对象作为返回值.对"大对象"的强调指的是不必要地重复对象的副本是浪费的循环.

使用对大对象的引用:

void getObjData( LargeObj& a )
{
  a.reset() ;
  a.fillWithData() ;
}

int main()
{
  LargeObj a ;
  getObjData( a ) ;
}
Run Code Online (Sandbox Code Playgroud)

使用大对象作为返回值:

LargeObj getObjData()
{
  LargeObj a ;
  a.fillWithData() ;
  return a ;
}

int main()
{
  LargeObj a = getObjData() ;
}
Run Code Online (Sandbox Code Playgroud)

第一段代码不需要复制大对象.

在第二个片段中,对象是在函数内部创建的,因此通常在返回对象时需要复制.但是,在这种情况下,main()正在声明对象.编译器是否会首先创建一个默认构造的对象,然后复制返回的对象getObjData(),或者它是否与第一个片段一样有效?

我认为第二个片段更容易阅读,但我担心效率会降低.

编辑:通常,我认为案例LargeObj是通用容器类,为了参数,它们包含数千个对象.例如,

typedef std::vector<HugeObj> LargeObj ;
Run Code Online (Sandbox Code Playgroud)

所以直接修改/添加方法LargeObj不是一个可直接访问的解决方案.

c++

40
推荐指数
2
解决办法
7240
查看次数

移动或命名返回值优化(NRVO)?

可以说我们有以下代码:

std::vector<int> f()
{
  std::vector<int> y;
  ...
  return y;
} 

std::vector<int> x = ...
x = f();
Run Code Online (Sandbox Code Playgroud)

看来编译器有两种方法:

(a)NRVO:Destruct x,然后构造f()代替x.
(b)移动:在temp空间中构造f(),将f()移动到x,destruct f().

根据标准,编译器是否可以自由使用这两种方法?

c++ optimization move-semantics return-value-optimization c++11

32
推荐指数
1
解决办法
2万
查看次数

函数返回右值引用有意义吗?

这样的签名有效的用例是什么?:

T&& foo();
Run Code Online (Sandbox Code Playgroud)

还是右值引用仅打算用作参数?

如何使用这样的功能?

T&& t = foo(); // is this a thing? And when would t get destructed?
Run Code Online (Sandbox Code Playgroud)

c++

26
推荐指数
3
解决办法
1255
查看次数

我应该通过右值参考返回rvalue参考参数吗?

我有一个函数可以std::string&就地修改左值引用,返回对输入参数的引用:

std::string& transform(std::string& input)
{
    // transform the input string
    ...

    return input;
}
Run Code Online (Sandbox Code Playgroud)

我有一个辅助函数,它允许在右值引用上执行相同的内联转换:

std::string&& transform(std::string&& input)
{
    return std::move(transform(input)); // calls the lvalue reference version
}
Run Code Online (Sandbox Code Playgroud)

请注意,它返回一个右值引用.

我已经阅读了关于返回右值引用的SO的几个问题(这里这里例如),并得出结论这是不好的做法.

根据我的阅读,似乎共识是因为返回值 rvalues,再加上考虑RVO,只需按值返回就会有效:

std::string transform(std::string&& input)
{
    return transform(input); // calls the lvalue reference version
}
Run Code Online (Sandbox Code Playgroud)

但是,我还读到返回函数参数会阻止RVO优化(例如此处此处)

这使我相信std::string&从左值参考版本transform(...)std::string返回值到返回值会发生副本.

那是对的吗?

保留我的std::string&& transform(...)版本会更好吗?

c++ move c++11

23
推荐指数
1
解决办法
2528
查看次数

为什么我应该按值返回一些东西,因为C++具有const引用?

考虑这个功能:

Thing func(){
    return something;
}
Run Code Online (Sandbox Code Playgroud)

每次调用此函数时,都会生成一个副本something并传递给调用者.

我的问题是,为什么不这样做(每次我想按价值归还)?

const Thing& func(){
    return something;
}
Run Code Online (Sandbox Code Playgroud)

这样,我们就没有冒充无法复制的风险something.如果客户端只需要"读取" something而不是"写入"它,那么const引用就可以完全实现.如果客户端确实需要副本,它可以简单地将const引用分配给变量,例如:

Thing thing = func(); // the object is passed by const reference, and then copied.
Run Code Online (Sandbox Code Playgroud)

那么,有没有理由简单地按价值回报?

顺便说一句,并不是因为我非常关心优化,只是因为我没有理由单纯地通过价值来回报.


跟进问题:阅读答案,我知道每种方法都有利弊.有违约吗?例如"默认按值返回"?或者它纯粹基于具体案例?

c++ const reference function

19
推荐指数
3
解决办法
2032
查看次数

重载R值引用和代码重复

考虑以下:

struct vec
{
    int v[3];

    vec() : v() {};
    vec(int x, int y, int z) : v{x,y,z} {};
    vec(const vec& that) = default;
    vec& operator=(const vec& that) = default;
    ~vec() = default;

    vec& operator+=(const vec& that)
    {
        v[0] += that.v[0];
        v[1] += that.v[1];
        v[2] += that.v[2];
        return *this;
    }
};

vec operator+(const vec& lhs, const vec& rhs)
{
    return vec(lhs.v[0] + rhs.v[0], lhs.v[1] + rhs.v[1], lhs.v[2] + rhs.v[2]);
}
vec&& operator+(vec&& lhs, const vec& rhs)
{
    return move(lhs += …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference c++11

15
推荐指数
3
解决办法
4757
查看次数

使用std :: move c ++ 11之后会持续多久

在一个变量中使用std :: move之后,该变量可能是类中的一个字段,如:

class A {
  public:
    vector<string>&& stealVector() {
      return std::move(myVector);
    }
    void recreateMyVector() {
    }
  private:
    vector<string> myVector;        
};
Run Code Online (Sandbox Code Playgroud)

我如何重新创建矢量,就像一个清晰的矢量?在std :: move之后myVector中还剩下什么?

c++ c++11

15
推荐指数
3
解决办法
5630
查看次数

成员函数上的Const引用限定符

我在anwser中看到过: 通过右值引用返回更有效率吗?

成员函数定义:

Beta_ab const& getAB() const& { return ab; }
Run Code Online (Sandbox Code Playgroud)

我熟悉成员函数的cv-qualifier(const),但不熟悉const&.

最后的const&意思是什么?

c++ reference member-functions const-reference

12
推荐指数
2
解决办法
3705
查看次数

返回值还是右值参考?

在Scott Meyer的新书中,他提出了rvalue引用限定符的示例用法,如下所示:

class Widget {
private:
    DataType values;

public:
    DataType& data() &  { return values; } 
    DataType  data() && { return std::move(values); } // why DataType?
};
Run Code Online (Sandbox Code Playgroud)

以便:

auto values = makeWidget().data();
Run Code Online (Sandbox Code Playgroud)

移动构造values而不是复制构造它.

为什么rvalue-ref-qualified data()返回DataType而不是DataType&&?在这种情况下auto仍会推断DataType(虽然decltype(auto)不会 - 但这不是唯一的理由,更喜欢返回一个值而不是ravlue ref).这个高度投票的答案会返回一个rvalue ref,这对我来说在概念上更有意义.

c++ rvalue-reference c++11

12
推荐指数
1
解决办法
2415
查看次数

在c ++ 11中使用rvalue引用

我想实现一个填充向量然后返回右值引用的函数.我厌倦了:

std::vector<int> &&fill_list() {
  std::vector<int> res;
  ... do something to fill res ...
  return res;
}

int main(int argc, char **argv) {
  std::vector<int> myvec = fill_list();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,我收到以下错误:

error: invalid initialization of reference of type 'std::vector<int>&&' from expression of type 'std::vector<int>'
Run Code Online (Sandbox Code Playgroud)

总而言之,正确的做法是怎样的?我认为我还没有获得右值参考.

c++ rvalue-reference c++11

9
推荐指数
1
解决办法
9156
查看次数