Variadic 模板的 C++ 错误

C++ errors with Variadic template

我有以下代码使用可变参数模板调用 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);
}

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

no matching function for call to 'async(std::launch, bool (TestChild::&)(int, int, bool&, std::vector&), TestParent, int&, int&, bool&, TestChild*&, std::vector*&)' startInx, endInx, nothingToCheck, args ... ) );

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

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

您将 this 与您的 Args 一起传递,这与您的函数参数不匹配,因此有一个额外的 TestChild*& 不属于。

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

去掉~~这个~~

此外,您应该 std::forward 您的 Args 这样:

                                        toCheck, std::forward<Args>(args) ... ) );

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

(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 的参数(通过异步调用)结束,但成员函数不会t 接受 TestChild* 来匹配 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));
}