【问题标题】:std::bind on member with call operatorstd::bind 与呼叫运算符的成员
【发布时间】:2017-05-01 09:06:43
【问题描述】:

这可能是一件愚蠢而愚蠢的事情 - 但是我想了解这里发生了什么。

我有以下代码:

#include <iostream>
#include <functional>

namespace
{
    struct call
    {
        void operator()() const
        {
            std::cout << "call::operator()" << std::endl;
        }
    };

    struct dummy
    {
        dummy() = default;
        dummy(const dummy&) = delete;

        call member;
    }; 
}

所以 member 基本上可以像任何其他对象方法一样工作,允许它被调用为:

dummy d;
d.member()

这将打印call::operator()

现在我想用 bind 来做这件事,最初的实现是这样的:

int main() 
{
    dummy d;

    auto b = std::bind(&dummy::member, &d);
    b();
    return 0;
}

这会编译,但没有打印任何内容。我真的不明白发生了什么 - 它编译但不产生输出的事实让我感到困惑 :) std::bind 的肚子里肯定发生了一些魔法,但是什么?

这是一个使用代码的链接: https://ideone.com/P81PND

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    目前,您的绑定返回一个成员,所以b()d.member。 你必须调用 operator () :

    b()(); // call::operator()
    

    作为替代方案,您可以使用以下任何一种:

    b = std::bind(&call::operator(), &d.member);
    b = [&]() {d.member();};
    

    【讨论】:

    • 你是对的! :) 我们只是自己发现了这一点。 std::bind 将返回会员,今天学到了新东西 - 谢谢!
    • @mortenvp:Lambdas 渲染 std::bind 无论如何都没什么用。已经讨论过在未来的 C++ 版本中弃用它。见stackoverflow.com/questions/33835922/…
    • @Jarod42,令人惊讶的是,std::cref - 见下文。
    【解决方案2】:

    您也可以拨打std::reference_wrapper。根本不需要bind

    int main() 
    {
        dummy d;
    
        auto b= std::cref(d.member);  // create reference wrapper
        b();
        return 0;
    }
    

    【讨论】:

    • 或常规参考。
    猜你喜欢
    • 2013-07-15
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多