【问题标题】:std::bind won't accept an std::cref of a bind-placeholder - why?std::bind 不接受绑定占位符的 std::cref - 为什么?
【发布时间】:2020-03-12 16:06:33
【问题描述】:

我尝试通过使用 std::cref 将方法作为参数函数传递,该方法本身接受参数,但不知何故我无法正确处理。怎么了?

struct node 
{
    void get(int &i){ 
        i = x; 
    }

    int x, z;
    void foo(std::function<void(int&)>t){ 
        t(z); 
    }

    void bar(){
        x = 7;
        z = 10;
        foo(std::bind(&node::get, this, std::cref(_1)));

        cout<< "z:" << z << std::endl; //Here is expected that z is changed to 7
    }
};

【问题讨论】:

  • Lambda 意味着没有真正的理由需要在新代码中使用 std::bind()...
  • @HolyBlackCat 指出问题在于std::cref的使用;您显然可以使用_1。但我会让 HolyBlackCat 自己写答案。
  • std::cref 创建了一个对const T 的引用,但get() 引用了一个非常量int,所以你为什么期望这种绑定能够编译,甚至像这样包装_1 占位符是否合法?

标签: c++ function c++11 methods bind


【解决方案1】:

std::bind只能将占位符直接作为参数处理:std::bind(…, _1, …)

std::cref(_1) 将占位符包装在 std::reference_wrapper 中。 bind 不再将其识别为占位符,并尝试将其直接传递给绑定函数,就像处理任何其他非占位符参数一样。

要解决 bind 的这一限制和其他限制,请使用 lambda:

foo([this](int &x){return get(std::ref(x));});

我在这里用ref 替换了cref,因为get() 需要一个非常量引用。你不能在这里使用cref,不管有没有lambda。 (注意std::ref(x) 在这里等同于x,用于代替x 仅用于演示目的。)

【讨论】:

  • 你不需要 lambda 中的std::ref,因为x 已经是一个引用,而get() 需要一个引用:foo([this](int &amp;x){return get(x);});
  • @RemyLebeau 是的。我用它来证明它可以与 lambda 一起使用(与 bind 不同)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
相关资源
最近更新 更多