Ошибки C ++ с шаблоном Variadic - PullRequest
       23

Ошибки C ++ с шаблоном Variadic

0 голосов
/ 06 ноября 2018

У меня есть следующий код, использующий шаблоны переменных для вызова 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, noneToCheck, args ...));

Я думаю, это может быть связано с тем, что я передаю дополнительные параметры вместе с пакетом параметров. У кого-нибудь есть идеи, что с этим не так, и что я должен сделать, чтобы это сработало?

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Это две основные проблемы в коде:

(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* для сопоставления 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));
}
0 голосов
/ 06 ноября 2018
return checkBlock( toCheck, &testChild::checkRules, this, &results);

Вы передаете this с вашим Args, который не соответствует вашим параметрам вашей функции, поэтому есть дополнительный TestChild*&, который не принадлежит.

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

Просто удалите ~~ этот ~~

Кроме того, вы должны std :: переслать ваш Args как таковой:

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