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

时间:2014-08-25 02:05:34

标签: c++ c++11

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

1 个答案:

答案 0 :(得分: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());
}

<强>输出

Obj::Obj()
Obj::Obj(Obj &&)
Obj::Obj(Obj &&)
void foo(Obj, Obj)

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