将r值作为非const引用传递(VS警告C4239)

Cod*_*Dan 4 c++ rvalue rvalue-reference c++11

我想做的事情(使用C++ lambda)是有效的:

std::vector<MyType> GetTheArray () {return something;}

const auto DoSomething = [](std::vector<MyType> & array)
{
     //Some processing that involves either sorting the 'array' or setting temporary flags on the items
};

DoSomething (GetTheArray ());
Run Code Online (Sandbox Code Playgroud)

这在标准C++中似乎是不允许的,因为rvalue不能作为非const引用传递.

我的问题:

1)有没有办法使用类型转换来执行此操作或我是否有义务创建一个临时变量来存储GetTheArray()的结果?

2)C++中不允许这样做是否有充分的理由?

请注意,'GetTheArray'返回的'something'是一个即时构建的数组,而不是存储值.

Dav*_*eas 6

从评论中可以看出,您想要的是采用矢量,破坏性地修改它(在原始状态无法重置的意义上),然后在内部使用结果.并且您希望这对于左值和右值都有效.

接下来的问题是,在左值的情况下,在函数调用完成后,保存原始容器的代码是否需要它,以及它是否需要向量的原始状态.根据您的答案,您有不同的解决方案:

持有左值的呼叫者在通话后不再使用它

(或者,持有左值的呼叫者需要原始状态)

这是最简单的情况.然后你的函数应该按值获取容器.如果调用者有一个左值,它std::move可以避免复制(它不再关心对象)或复制可能更昂贵但保持原始容器不变.

如果使用rvalue调用该函数,则该副本将被省略或转换为廉价的隐式移动.

持有左值的调用者不需要原始状态,但需要容器

这种情况很难,你需要为同一个函数(或lambda)提供两个重载,一个使用左值来调用这个调用者,另一个采用rvalue-reference来调用这个函数.临时.在这两种情况下,绑定都很便宜.虽然这需要更多代码,但您可以根据另一个实现一个重载:

rtype f(std::vector<Data> & );   // for lvalues
rtype f(std::vector<Data> && v)  // for rvalues
   { return f(v); }              // v is an lvalue here
Run Code Online (Sandbox Code Playgroud)

你正在做lambdas的事实可能会使这个稍微复杂一点,但希望不会太多.