【问题标题】:std::async with a member function, holding another meber fucntion as an argument带有成员函数的 std::async,将另一个成员函数作为参数
【发布时间】:2020-11-19 00:23:44
【问题描述】:

我有以下课程:

class Test
{
public:   
   void Func1(std::string const& a, std::string const& b, std::function<void(std::vector<double> const&, int)> func);   
   std::vector<double> Func2(std::vector<double> const& v, size_t const i);
};

异步调用我做的函数 Func1:

Test te;
auto fa = std::bind(&Test::Func2, &te, _1, _2);
auto fb = std::bind(&Test::Func1, &te, a, b, fa);
    
auto fab = std::async(std::launch::async, fb);

“fa”和“fb”可以编译,但异步调用“fab”没有。我应该如何调用 Func1 的 std::async?

【问题讨论】:

    标签: c++ c++17 member std-function stdasync


    【解决方案1】:

    fafb 在您实际调用它们之前不会完全“编译”——函数调用运算符似乎直到那时才被实例化。一旦你调用,你会发现fb 是无效的,即fb() 不会编译。一旦你解决了这个问题,async 电话就会起作用:)

    作为进一步的提示,请注意 std::bind 被巧妙地破坏,不推荐用于新代码。 lambdas 会更好地为您服务(它们实际上可以在这里工作!)。

    绑定是如何被破坏的?像这样:

    std::bind(&Test::Func1, &te, a, b, fa)(); // won't compile
    

    但是:

    using FnArg = std::function<void(std::vector<double> const&, int)>;
    fb = std::bind(&Test::Func1, &te, a, b, FnArg(fa));
    fb(); // compiles OK
    

    因此,最好忘记std::bind 的存在,并使用 lambdas:

    #include <functional>
    #include <future>
    #include <string>
    #include <vector>
    
    class Test
    {
    public:
        using FnArg = std::function<void(std::vector<double> const&, int)>;
        void Func1(std::string const&, std::string const&, FnArg) {}
        std::vector<double> Func2(std::vector<double> const&, size_t const) {}
    };
    
    int main()
    {
        Test te;
        std::vector<double> vd;
        std::string a, b;
        auto fa = [&te](const auto &a, auto b){ return te.Func2(a, b); };
        auto fb = [=,&te](){ return te.Func1(a, b, fa); };
        fa(vd, 1);
        fb();
            
        auto fab = std::async(std::launch::async, fb);
        fab.wait();
    }
    

    请随意online

    【讨论】:

    • 完美,它可以满足我的需要!您能否详细说明或提供链接,关于您的声明“std::bind 被巧妙地破坏,不推荐用于新代码”?谢谢。
    • 你还需要什么证据证明它坏了?它不起作用!这就是你的问题的全部内容。你不会问它是否有效!您可以将给定的参数直接传递给函数并且它会接受它,但是当您绑定相同的参数时,生成的仿函数不会编译。这就是std::bind 的破碎程度。期望std::bind 包装了一个函数调用,所以如果fun(a,b,c,d) 有效,那么您希望std::bind(&amp;fun, a, b, c, d)() 也能有效。正如你已经证明的那样,事实并非如此。不要使用它。它坏了:)
    猜你喜欢
    • 2016-09-11
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 2013-02-01
    • 2015-04-12
    • 1970-01-01
    • 2013-06-29
    • 2020-12-31
    相关资源
    最近更新 更多