使用可变数量的参数存储 boost::function 对象
Storing boost::function object with variable number of arguments
我想要实现的是创建一个存储任何类型方法的结构。我稍后可以调用 struct_object.run() 来 运行 我存储的方法。
此方法可以return任何类型的值,最重要的是,可以使用任意数量的参数;但是,我无法解决 "any amount of parameters" 问题。
请注意,以下代码甚至无法构建,主要是因为我不知道正确的语法是什么样的。
ApplicationPair.h
template<typename T, typename... Args>
struct ApplicationPair
{
ApplicationPair(boost::function<T()> func, Args... arguments )
{
_func = func(Args::arguments...);
}
ApplicationPair() = delete;
void run();
boost::function<T(Args...)> _func;
};
#endif
然后,我想做的是:
main.cpp
template<typename T, typename... Args>
void ApplicationPair<T,Args...>::run()
{
this->_func;
}
//TEST
int counter = 0;
void HelloWorld()
{
std::cout << "HelloWorld\n";
}
void printNumber(int i)
{
std::cout << "Print: " << i << std::endl;
}
void increaseCounter(int x)
{
counter+=x;
}
int main()
{
ApplicationPair<void> p1(HelloWorld);
ApplicationPair<void> p2(printNumber, 5);
ApplicationPair<void> p3(increaseCounter, 10);
p1.run();
p2.run();
p3.run();
return 0;
}
基本上,我想要存储的方法不应该以任何方式修改或改编:我希望能够创建任何类型的方法而不用关心 struct ApplicationPair 会为自己的个人存储它这一事实使用。
尽管如此,我得到的只是一长串错误,例如:
error: in declaration ‘typename boost::enable_if_c<(! boost::is_integral::value), boost::function&>::type boost::function::operator=(Functor)’
在下一行中:
ApplicationPair<void> p2(printNumber, 5);
你必须在模板参数列表中指定所有类型,不仅 void
作为 return 类型,还应添加 int
作为构造函数的参数。现在 args...
是空的。怎么了。与 p3
.
相同
将构造函数作为模板化方法,将参数包作为可调用对象的参数:
template<class F, class ... Args>
ApplicationPair(F&& func, Args... arguments )
{
_func = boost::bind(std::forward<F>(func),arguments...);
}
则在调用构造函数时可以推导出args...
。您的 class 模板仅采用 return 值的类型。
template<class Ret>
struct ApplicationPair {
template<class F, class ... Args>
ApplicationPair(F&& func, Args... arguments )
{
_func = boost::bind(std::forward<F>(func),arguments...);
}
ApplicationPair() = delete;
void run() {
this->_func();
}
boost::function<Ret()> _func;
};
在构造函数中boost::bind
用于将传递的参数绑定到可调用的。您不会在任何地方存储参数,因此它们必须绑定在由 boost::bind
.
创建的函子中
使用:
ApplicationPair<void> p1(HelloWorld);
ApplicationPair<void> p2(printNumber, 5);
ApplicationPair<void> p3(increaseCounter, 10);
不要使用 boost::bind
,它最多只能处理 9 个参数。
你已经得到了答案,但这里有一个 C++17 替代方案,能够使用推导指南推导 return 值类型以及函数的参数类型,从而使 return 类型和参数类型是 ApplicationPair<>
类型的一部分。我选择将参数单独存储在 std::tuple<Args...>
.
中
在此示例中,boost::function
可以替换为 std::function
,以防您以后决定使用标准:
#include <boost/function.hpp>
#include <iostream>
#include <type_traits>
#include <tuple>
template<typename T, typename... Args>
struct ApplicationPair {
ApplicationPair() = delete;
ApplicationPair(Func func, Args... args) :
_func(func),
// store the arguments for later use
arguments(std::make_tuple(std::forward<Args>(args)...))
{}
decltype(auto) run() { // I'd rename this: decltype(auto) operator()()
return std::apply(_func, arguments);
}
boost::function<T(Args...)> _func;
std::tuple<Args...> arguments;
};
// deduction guide
template<typename Func, typename... Args>
ApplicationPair(Func, Args...) ->
ApplicationPair<std::invoke_result_t<Func, Args...>, Args...>;
int counter = 0;
void HelloWorld()
{
std::cout << "HelloWorld\n";
}
void printNumber(int i)
{
std::cout << "Print: " << i << std::endl;
}
int increaseCounter(int x) // changed return type for demo
{
counter+=x;
return counter;
}
int main()
{
// full deduction using the deduction guide
ApplicationPair p1(HelloWorld);
ApplicationPair p2(printNumber, 5);
ApplicationPair p3(increaseCounter, 10);
p1.run();
p2.run();
std::cout << p3.run() << '\n';
std::cout << p3.run() << '\n';
}
我想要实现的是创建一个存储任何类型方法的结构。我稍后可以调用 struct_object.run() 来 运行 我存储的方法。
此方法可以return任何类型的值,最重要的是,可以使用任意数量的参数;但是,我无法解决 "any amount of parameters" 问题。
请注意,以下代码甚至无法构建,主要是因为我不知道正确的语法是什么样的。
ApplicationPair.h
template<typename T, typename... Args>
struct ApplicationPair
{
ApplicationPair(boost::function<T()> func, Args... arguments )
{
_func = func(Args::arguments...);
}
ApplicationPair() = delete;
void run();
boost::function<T(Args...)> _func;
};
#endif
然后,我想做的是:
main.cpp
template<typename T, typename... Args>
void ApplicationPair<T,Args...>::run()
{
this->_func;
}
//TEST
int counter = 0;
void HelloWorld()
{
std::cout << "HelloWorld\n";
}
void printNumber(int i)
{
std::cout << "Print: " << i << std::endl;
}
void increaseCounter(int x)
{
counter+=x;
}
int main()
{
ApplicationPair<void> p1(HelloWorld);
ApplicationPair<void> p2(printNumber, 5);
ApplicationPair<void> p3(increaseCounter, 10);
p1.run();
p2.run();
p3.run();
return 0;
}
基本上,我想要存储的方法不应该以任何方式修改或改编:我希望能够创建任何类型的方法而不用关心 struct ApplicationPair 会为自己的个人存储它这一事实使用。
尽管如此,我得到的只是一长串错误,例如:
error: in declaration ‘typename boost::enable_if_c<(! boost::is_integral::value), boost::function&>::type boost::function::operator=(Functor)’
在下一行中:
ApplicationPair<void> p2(printNumber, 5);
你必须在模板参数列表中指定所有类型,不仅 void
作为 return 类型,还应添加 int
作为构造函数的参数。现在 args...
是空的。怎么了。与 p3
.
将构造函数作为模板化方法,将参数包作为可调用对象的参数:
template<class F, class ... Args>
ApplicationPair(F&& func, Args... arguments )
{
_func = boost::bind(std::forward<F>(func),arguments...);
}
则在调用构造函数时可以推导出args...
。您的 class 模板仅采用 return 值的类型。
template<class Ret>
struct ApplicationPair {
template<class F, class ... Args>
ApplicationPair(F&& func, Args... arguments )
{
_func = boost::bind(std::forward<F>(func),arguments...);
}
ApplicationPair() = delete;
void run() {
this->_func();
}
boost::function<Ret()> _func;
};
在构造函数中boost::bind
用于将传递的参数绑定到可调用的。您不会在任何地方存储参数,因此它们必须绑定在由 boost::bind
.
使用:
ApplicationPair<void> p1(HelloWorld);
ApplicationPair<void> p2(printNumber, 5);
ApplicationPair<void> p3(increaseCounter, 10);
不要使用 boost::bind
,它最多只能处理 9 个参数。
你已经得到了答案,但这里有一个 C++17 替代方案,能够使用推导指南推导 return 值类型以及函数的参数类型,从而使 return 类型和参数类型是 ApplicationPair<>
类型的一部分。我选择将参数单独存储在 std::tuple<Args...>
.
boost::function
可以替换为 std::function
,以防您以后决定使用标准:
#include <boost/function.hpp>
#include <iostream>
#include <type_traits>
#include <tuple>
template<typename T, typename... Args>
struct ApplicationPair {
ApplicationPair() = delete;
ApplicationPair(Func func, Args... args) :
_func(func),
// store the arguments for later use
arguments(std::make_tuple(std::forward<Args>(args)...))
{}
decltype(auto) run() { // I'd rename this: decltype(auto) operator()()
return std::apply(_func, arguments);
}
boost::function<T(Args...)> _func;
std::tuple<Args...> arguments;
};
// deduction guide
template<typename Func, typename... Args>
ApplicationPair(Func, Args...) ->
ApplicationPair<std::invoke_result_t<Func, Args...>, Args...>;
int counter = 0;
void HelloWorld()
{
std::cout << "HelloWorld\n";
}
void printNumber(int i)
{
std::cout << "Print: " << i << std::endl;
}
int increaseCounter(int x) // changed return type for demo
{
counter+=x;
return counter;
}
int main()
{
// full deduction using the deduction guide
ApplicationPair p1(HelloWorld);
ApplicationPair p2(printNumber, 5);
ApplicationPair p3(increaseCounter, 10);
p1.run();
p2.run();
std::cout << p3.run() << '\n';
std::cout << p3.run() << '\n';
}