将指向成员的指针从模板参数包传递给函数对象
Passing pointers to member to function object from template parameter pack
Bellow 是演示我正在尝试做的事情的示例代码。
基本上我想将多个指向成员的指针传递给 class 方法,该方法采用 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;
}
正如评论中所讨论的,假设所有参数都需要相同的操作,您可以简单地在参数包扩展中应用任何 dereferencing/member 访问操作。例如。对于应该访问 this
实例的成员指针:
target(this->*params...);
或者如果你直接传递对象指针(这对我来说似乎更直接):
target(*params...);
//...
t.RunTargetAlgo(algo, &t.mLoop, &t.mLoopMax);
Bellow 是演示我正在尝试做的事情的示例代码。
基本上我想将多个指向成员的指针传递给 class 方法,该方法采用 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;
}
正如评论中所讨论的,假设所有参数都需要相同的操作,您可以简单地在参数包扩展中应用任何 dereferencing/member 访问操作。例如。对于应该访问 this
实例的成员指针:
target(this->*params...);
或者如果你直接传递对象指针(这对我来说似乎更直接):
target(*params...);
//...
t.RunTargetAlgo(algo, &t.mLoop, &t.mLoopMax);