我如何知道作为r值传递的对象是否会移动?

时间:2018-11-04 21:47:32

标签: c++11 lambda move-semantics forwarding-reference

我正在将lambda传递给接受它作为r值引用的函数。

如果我的lambda是在函数调用本身中定义的,那么我真的不在乎以后会发生什么。
但是,如果我的lambda是一个变量(例如,我想多次使用它),我确实想知道它不是从源中移出的。

有没有办法知道是否将其移出,从而在呼叫返回后相应地使其不可用或可用?

编辑:

只需澄清一下,lambda不会捕获任何内容。我关心的是函子本身:auto fn = [](int a){ return a; };

让我变得更加艰难。我将函子作为右值传递:std::move(fn)

std :: move只是强制转换。它不会移动任何东西,但被调用方中的rvalue参数现在绑定到正确的rvalue。

问题是,fn是否一定会受到感动?是否保证不被打动?有什么保证吗?我可以使其表现为这种方式还是由被调用者决定?

我想知道,因为我想知道可以两次将fn作为函数参数进行传递。

编辑#2:

让我们再举一个例子。我必须使用容器调用函数。矢量,地图或其他任何内容。函数签名显示&&。 我可以使用std move或std forward包装我的容器,以将右值引用放入被调用方。他们都是光荣的演员,确实是同一回事。

现在,假设我使用了std forward,因为我真的很喜欢我的容器不要放在任何地方。

我可以很容易地看到被呼叫者没有意识到我的意图,并在呼叫后移动容器使其无效(被破坏)。 这是语言缺陷还是我缺少什么?

1 个答案:

答案 0 :(得分:3)

好吧,如果该函数接受通用引用并且您要禁止移动,那么有很多选项可供您选择,

  1. 通过常量引用传递(C ++ 17具有std::as_const()来简化这一点)。
  2. 将其另存为本地,不转换为右值引用。看来您是这样做的。
  3. 使用一些东西将右值引用显式转换为左值引用。

当然,除非lambda通过值捕获具有与复制语义不同的移动语义的局部值,并且所调用的函数实际上利用了这一点,否则这一点是没有意义的。

实际上会抓住机会吗?
检查合同,然后简单地信任它或尝试验证实施。没有捷径。

我们什至没有提到C ++允许程序员明确选择退出其提供的(有限)安全性。