我怎么知道作为右值传递的对象是否会被移动?

How do I know if object passed as r-value will get moved?

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

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

有没有办法知道它是否会被移动,从而在调用返回后相应地使其不可用或可用?

编辑:

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

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

std::move 只是一个转换。它不会移动任何东西,但被调用者中的右值参数现在绑定到正确的右值。

问题是,fn能保证感动吗?能保证不搬家吗?有任何保证吗?我可以让它以这种或那种方式表现还是由被调用者决定?

我想知道,因为我想知道我可以将 fn 作为函数参数传递两次吗?

编辑#2:

我们再来看一个案例。我必须调用一个带有容器的函数。矢量、地图或其他任何内容。函数签名表示 &&。 我可以用 std move 或 std forward 包装我的容器,以将右值引用放入被调用方。这真的是一回事,因为他们都是美化演员。

现在,假设我使用了 std forward,因为我真的希望我的容器不会去任何地方。

我可以很容易地看到被调用者没有意识到我的意图,并在调用后移动我的容器使其无效(内脏)。 这是语言缺陷还是我遗漏了什么?

好吧,如果函数接受通用引用并且你想禁止移动,有很多选项供你选择,其中包括:

  1. 通过常量引用传递(C++17 有 std::as_const() 来简化它)。
  2. 将其保存为本地文件,不要转换为右值引用。看来你这样做了。
  3. 使用一些东西将右值引用显式转换为左值引用。

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

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

更不用说 C++ 允许程序员明确选择退出它提供的(有限的)安全性。