【问题标题】:Passing pointers to member to function object from template parameter pack从模板参数包将成员指针传递给函数对象
【发布时间】:2020-04-29 00:13:15
【问题描述】:

下面是示例代码,它演示了我正在尝试做的事情。

基本上,我想将多个指向成员的指针传递给类方法,该方法采用std::function 对象和传递给目标函数对象的变量号或参数。

这些可变参数可以是任何东西:变量、指向成员的指针等。

使用普通变量时我没有问题,但是如何扩展参数包,其中参数是指向成员的指针,但函数对象需要 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;
}

【问题讨论】:

  • 为什么需要成员指针?您想在RunTargetAlgo 中引用哪个实例的成员? t 的?如果是这样,为什么不只是普通的对象指针:t.RunTargetAlgo(algo, &amp;t.mLoop, &amp;t.mLoopMax);
  • @walnut 是的,这也是可能的,但问题是这些参数仍然是地址而不是实际值,我需要将这些地址解引用为值,并以某种方式从 RunTargetAlgo 内的参数包中扩展它们
  • target(*params...);?
  • 嗯,我给你一杯啤酒! :)

标签: c++ templates member-pointers parameter-pack


【解决方案1】:

正如 cmets 中所讨论的,假设所有参数都需要相同的操作,您可以简单地在参数包扩展中应用任何取消引用/成员访问操作。例如。对于应该访问this 实例的成员指针:

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

或者如果你直接传递对象指针(这对我来说似乎更直接):

target(*params...);

//...

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 2020-10-26
    • 1970-01-01
    • 2017-03-17
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多