Передача указателей члену на функциональный объект из пакета параметров шаблона - PullRequest
0 голосов
/ 11 января 2020

Ниже приведен пример кода, демонстрирующий то, что я пытаюсь сделать.

В основном я хочу передать более одного указателя на член в метод класса, который принимает std::function объект и переменную номер или аргументы, которые передаются для целевого объекта функции.

эти параметры переменных могут быть любыми: переменные, указатели на члены и т. д. c ..

У меня нет проблем при работе с простыми переменными, но как расширить параметр? Пакет, в котором параметры являются указателями на члены, но объект функции ожидает типы данных POD?

Как получить значение указателя на член в пакете параметров и передать его объекту функции?

#include <cstddef>
#include <functional>


class Test
{
public:
    inline Test(std::uint32_t max);

    template<typename ReturnType, typename... Args>
    using Algorithm = std::function<ReturnType(Args...)>;

    // pointer to member
    // not used but would like to make use of it in 'RunTargetAlgo'
    template<typename T>
    using ParamType = T Test::*;

    // exectutor
    template<typename ReturnType, typename... Args, typename... Params>
    inline double RunTargetAlgo(Algorithm<ReturnType, Args...> target, Params... params);

    std::uint32_t mLoop = 0;
    const std::size_t mLoopMax;
    double mPrecision = 0;
};

Test::Test(std::uint32_t max) :
    mLoopMax(max)
{
}

template<typename ReturnType, typename ...Args, typename ...Params>
double Test::RunTargetAlgo(Algorithm<ReturnType, Args...> target, Params ...params)
{
    while (++mLoop <= mLoopMax)
        mPrecision += target(params...);    // How if Params == Test::ParamType ??

    // ... in real code we measure bunch of other stuff here...

    return mPrecision;
}

template<typename RetrunType>
RetrunType TestAlgorithm(std::uint32_t x, std::uint32_t y)
{
    // ...
    return RetrunType();
}

int main()
{
    namespace pl = std::placeholders;

    Test::Algorithm<double, std::uint32_t, std::uint32_t> algo =
        std::bind(TestAlgorithm<double>, pl::_1, pl::_2);

    Test t(50);

    // this works just fine!
    t.RunTargetAlgo(algo, 3u, 4u);

    // but how to run this?
    // I need pass fresh data to target algorithm, value of
    // pointer to members may change anytime.
    // but main issue here is how to extract these pointer from
    // parameter pack into actual values, but inside Test::RunTargetAlgo?
    t.RunTargetAlgo(algo, &Test::mLoop, &Test::mLoopMax);

    return 0;
}

1 Ответ

2 голосов
/ 11 января 2020

Как обсуждалось в комментариях, предполагая, что для всех аргументов требуется одно и то же действие, вы можете просто применить любую операцию разыменования / доступа к члену в расширении пакета параметров. Например, для указателей элементов, которые должны обращаться к экземпляру this:

target(this->*params...);

или если вы передаете указатели объектов напрямую (что мне кажется гораздо более простым):

target(*params...);

//...

t.RunTargetAlgo(algo, &t.mLoop, &t.mLoopMax);
...