使用std :: bind和重复占位符的未定义结果

Don*_*nir 6 c++ c++11

我在查看std::bindcppreference 页面上的注释部分时遇到了一些问题:它表示当重复的占位符出现在同一个绑定表达式中时 - 例如多个_1' - 仅当u1是左值或者结果时才能很好地定义结果不可移动的右值.有人可以给出一个不明确定义的例子吗?

Who*_*aig 7

以下可能是我能想到的最简单的例子(考虑到我对rvalues的熟悉程度,这正在推动我的极限).

首先是代码(可能太简单,但我认为它对于演示是正确的):

#include <iostream>
#include <utility>
#include <functional>

struct Obj
{
    Obj()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }

    Obj(Obj const&)
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }

    Obj(Obj&&)
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};

void foo(Obj, Obj)
{
    std::cout << __PRETTY_FUNCTION__ << '\n';
}

int main()
{
    using namespace std::placeholders;
    auto fn = std::bind(foo, _1, _1);
    fn(Obj());
}
Run Code Online (Sandbox Code Playgroud)

产量

Obj::Obj()
Obj::Obj(Obj &&)
Obj::Obj(Obj &&)
void foo(Obj, Obj)
Run Code Online (Sandbox Code Playgroud)

重要的是明确的证据只有一个 Obj最初构建,但后来"移动"了两次,这对于移动语义来说是禁忌.第一次移动完成后,该物体处于炼狱状态.第二步没有明确定义,因为源对象不再明确定义.重复占位符不能是可移动的左值,或者您在此处看到的可能发生.