2

我有以下代码使用可变参数模板调用 std::async,

struct TestParent
{
    template< typename Fn, typeName ...Args >
    bool checkBlock( bool& toCheck,
                     Fn&& fn, Args&& ... args )
    {
        int startIndx = 0;
        int endIndx = 10;
        std::future< bool > tk( std::async( std::launch, fn, this,
                                            startIndx, endIndx, 
                                            toCheck, args ... ) );
        return tk.get();
     }
}

struct TestChild: public TestParent
{
    bool checkRules( const int, const int, bool& std::vector< bool >& );
    bool check();
}

bool TestChild::checkRules( const int startIndx, const int endIndx,
                            bool& toCheck,
                            std::vector< bool >& results )
{
    toCheck = true;
    for ( int indx = startIndx; indx < endIndx; ++ indx )
    {
        bool checkedOk;
        ... do something checking.
        results.push_back( checkedOk );
    }

    return true;
 }

bool TestChild::check()
{
    bool toCheck;
    std::vector< bool > results;
    return checkBlock( toCheck, &testChild::checkRules, this, &results);
}

但我收到以下编译错误消息:

没有匹配函数调用 'async(std::launch, bool (TestChild:: &)(int, int, bool&, std::vector&), TestParent , int&, int&, bool&, TestChild*&, std::vector *&)' startInx, endInx, nothingToCheck, args ... ) );

我认为这可能与我将附加参数与参数包一起传递的事实有关。任何人都知道这有什么问题,我应该怎么做才能让它发挥作用?

4

2 回答 2

3

这是代码中的两个主要问题:

(1)std::async在将所有传递的参数转发给提供的函数之前衰减所有传递的参数,这意味着引用参数与调用函数时尝试使用checkRules的类型不同,您需要进行以下更改:async

template< typename Fn, typename ...Args >
bool checkBlock( std::reference_wrapper<bool> const& toCheck,
                Fn&& fn, Args&& ... args )
{
    int startIndx = 0;
    int endIndx = 10;
    std::future< bool > tk(std::async(std::launch::async,
                                       std::forward<Fn>(fn),
                                       startIndx, endIndx,
                                       toCheck,
                                       std::forward<Args>(args) ... ) );
    return tk.get();
}

(2)您this作为参数传递checkBlock,最终将作为checkRules(通过异步调用)的参数,但成员函数不接受TestChild*match this。由于您使用的是指向成员函数的指针,因此async您需要使用std::bind来绑定this参数并std::wrap用于要更改的参数:

#include <functional>
using namespace std::placeholders;

bool TestChild::check()
{
    bool toCheck;
    std::vector< bool > results;
    return checkBlock( std::ref(toCheck), std::bind(&TestChild::checkRules, this, _1, _2, _3, _4), std::ref(results));
}
于 2018-11-06T00:20:31.220 回答
1
return checkBlock( toCheck, &testChild::checkRules, this, &results);

您传入thisArgs参数与您的函数不匹配,因此有一个TestChild*&不属于的额外内容。

return checkBlock( toCheck, &testChild::checkRules, ~~this~~, &results);

删掉~~这个~~

此外,你应该 std::forward 你Args这样:

                                        toCheck, std::forward<Args>(args) ... ) );
于 2018-11-05T22:46:13.280 回答