使用 boost::bind 但允许传递任何其他参数
Using boost::bind but allowing any additional parameters to be passed through
我正在整理一个"简单"的模板类。它提供了一个接口,用于对数据库执行某些操作,因此还有其他成员(主要用于对容器成员进行操作(。但是,出于我们的目的,模板类如下所示:
template<typename T, //the type of objects the class will be manipulating
typename S> //the signature of the function the class will be using
FunctionHandler
{
private:
std::vector<T> container;
boost::function<S> the_operation;
SomeClass* pSC; //a database connection; implementation unimportant
//some other members--not relevant here
public:
boost::function<???> Operate;
FunctionHandler(boost::function<S> the_operation_)
: the_operation(the_operation_)
{
Operate = boost::bind(the_operation, pSC, std::back_inserter<std::vector<T> >,
/*infer that all other parameters passed to Operate
should be passed through to the_operation*/);
}
//other peripheral functions
}
我的问题是双重的。
- 我应该把什么作为
Operate
的模板参数,即什么替换了???
- 我如何告诉
boost::bind
它应该将提供给Operate
的任何其他参数传递给the_operation
?换句话说,对于一些看起来像void (SomeClass*, std::back_insert_iterator<std::vector<T> >, int, bool)
的任意函数签名S
和其他一些看起来像void (SomeClass*, std::back_insert_iterator<std::vector<T> >, double, double, bool)
的任意函数签名O
,我如何编写这个模板类,以便Operate
第一个签名为void (int, bool)
,第二个签名为void (double, double, bool)
,并将其值传递给the_operation
的第 3-N 个参数?
在我的搜索中,我找不到任何像这样的问题。
为什么还要使用绑定?没有它,我们可以得到同样的效果。我正在使用Iter
作为模板,但您可以使用正确的类型来填充它:
template <typename S, typename Iter>
class Operator
{
boost::function<S> func_;
SomeClass* cls_;
Iter iter_;
public:
Operator(function<S> func, SomeClass* cls, Iter iter)
: func_(func), cls_(cls), iter_(iter)
{ }
// one for each # of args
typename boost::result_of<
boost::function<S>(SomeClass*, Iter)
>::type operator()() const {
return func_(cls_, iter_);
}
template <typename A>
typename boost::result_of<
boost::function<S>(SomeClass*, Iter, A)
>::type operator()(A a) const {
return func_(cls_, iter_, a);
}
template <typename A, typename B>
typename boost::result_of<
boost::function<S>(SomeClass*, Iter, A, B)
>::type operator()(A a, B b) const {
return func_(cls_, iter_, a, b);
}
// etc.
};
我们正在制作所有operator()
,但它们只有在被调用时才会被实例化 - 所以只要你调用正确的一个(对于任何解决方案,你无论如何都必须这样做(,这就可以了。
不幸的是,
没有办法"推断"所有其他参数。您必须指定所有正确的占位符。从 C++03 开始,我们只能使用大量的模板专业化。
template <typename S> struct Operate;
template <typename R, typename Iter>
struct Operate<R(SomeClass*, Iter)>
{
using namespace boost;
function<R()> op_;
Operator(function<R(SomeClass*, Iter)> op, SomeClass* cls, Iter iter)
: op_(bind(op, cls, iter))
{ }
};
template <typename R, typename Iter, typename A>
struct Operate<R(SomeClass*, Iter, A)>
{
using namespace boost;
function<R(A)> op_;
Operator(function<R(SomeClass*, Iter, A)> op, SomeClass* cls, Iter iter)
: op_(bind(op, cls, iter, _1))
{ }
};
template <typename R, typename Iter, typename A, typename B>
struct Operate<R(SomeClass*, Iter, A, B)>
{
using namespace boost;
function<R(A, B)> op_;
Operator(function<R(SomeClass*, Iter, A, B)> op, SomeClass* cls, Iter iter)
: op_(bind(op, cls, iter, _1, _2))
{ }
};
// etc.
这很冗长,但如果你不能使用 C++11,我不知道你还能做什么。其中,为了完整起见:
template <typename R, typename Iter, typename... Extra>
struct Operator<R(SomeClass*, Iter, Extra...)>
{
std::function<R(SomeClass*, Iter, Extra...)> op_;
SomeClass* cls_;
Iter iter_;
Operator(function<R(SomeClass*, Iter, Extra...)> op, SomeClass* cls, Iter iter)
: op_(op), cls_(cls), iter_(iter)
{ }
R operator()(Extra... args) const {
return op_(cls_, iter_, args...);
}
};
我对提升的了解。不幸的是,MPL 非常有限,因此我认为这不是解决从函数类型中删除前两个参数类型的问题的最好方法。
#include <boost/function_types/components.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/advance.hpp>
#include <boost/mpl/int.hpp>
template<typename F, int N>
class remove_first_N_param_types
{
typedef typename boost::function_types::components<F>::type
components;
typedef typename boost::mpl::begin<components>::type
beg;
typedef typename boost::mpl::advance<beg, boost::mpl::int_<1 >>::type
beg_param;
typedef typename boost::mpl::advance<beg, boost::mpl::int_<1+N>>::type
beg_param_plus_N;
typedef typename boost::mpl::erase<components,
beg_param, beg_param_plus_N>::type
erased_first_N_params;
public:
typedef typename boost::function_types::
function_type<erased_first_N_params>::type
type;
};
现场示例
相关文章:
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 为什么 c++ 中的 main() 函数不采用除 int 和 void 之外的任何其他返回类型
- 如何在不进行任何其他修改的情况下"pretty print" C++的XML字符串?
- 如何对 int 变量应用验证,使其仅接受整数数据,并且在任何其他数据的情况下不会出错?
- 如何计算该程序的复杂性?是否有任何其他复杂性较低的解决方案
- 如何使用"std::multimap"或任何其他容器对多个值进行排序?
- 如何在任何其他全局变量或静态变量之前创建/构造类实例
- SSO在STD :: String以外的任何其他标准库容器中使用
- OpenCV将一种颜色转换为任何其他颜色
- 如何使用QT或Linux上的任何其他CPP框架播放WMA音频文件
- 在构造函数以外的任何其他位置访问相机时,我的相机指针返回 null
- "size_t"是否始终是"vector<int>::size_type"或任何其他容器类型的别名?
- 来自没有默认构造函数的超级类的子类,而无需调用任何其他构造函数
- 我们还能使用任何其他方法来访问Android中的C 代码,而不是使用JNI访问C 代码
- 如何在 ubuntu 中单击任何其他歌曲后停止当前播放的歌曲
- 如何检查数组是否等于任何其他数组C++
- 我如何使用OCI或任何其他LIB登录Oracle作为SYS帐户
- 默认的Qt控制台应用程序不会"Hello World"...或做任何其他事情
- -fno elide构造函数是否包含在-O0或任何其他优化级别中