全局函数和非静态成员函数指针设计
Global function and non-static member function pointer design
我有一个连续优化算法,它以Oracle函数作为模板参数。具体的优化类定义为:
template<class Space, class Solution, class Oracle>
class ConjugateGradient : public ContinuousOptimizerInterface<Space, Solution, Oracle> {
public:
// Returns the optimal solution found for a given search space
virtual const Solution& search(const Space& space, Oracle f);
};
作为搜索实现的一部分,我调用了oracle函数:
template<class Space, class Solution, class Oracle>
inline const Solution& ConjugateGradient<Space, Solution, Oracle>::search(const Space& space, Oracle f) {
// ...
// get function value and gradient at X
double fx;
Solution dfx;
tie(fx, dfx) = f(X);
// ..
}
使用全局二次函数的简单示例:
typedef tuple<double, VectorXd> (*oracle_f)(const VectorXd&);
static tuple<double, VectorXd> f(const VectorXd& X) {
double f = pow((4.0-X(0)), 2) + 10.0;
VectorXd df = 2.0*X - VectorXd::Ones(X.rows())*8.0;
return make_tuple(f, df);
}
// ...
ConjugateGradient<TestSpace, VectorXd, oracle_f> optimizer;
VectorXd optimal = optimizer.search(TestSpace(), f);
这工作OK,但现在我需要能够传递一个类的非静态成员函数作为Oracle函数到ConjugateGradient
算法。我如何需要改变ConjugateGradient
模板声明和实现的oracle函数是一个全局函数或非静态成员函数?另一种方法是创建一个全局包装函数,并使用变量将参数传递给包装函数,但这很难看,也不类型安全。
UPDATE:这个例子使用了下面答案的绑定思想,但是使用boost::bind而不是std::bind,因为我不是在c++ 11上,std::bind只在c++ 11上可用。
#include <Eigen/Dense>
#include <boost/tuple/tuple.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
using namespace Eigen;
using namespace boost;
// the class is parameterized with the appropriate minimizer strategy
enum Minimizer { kNormalEquations, kConjugateGradient };
template <Minimizer M = kNormalEquations>
class SomeANN : AnnInterface {
private:
// ...
public:
// define the oracle function type and member function
typedef tuple<double, VectorXd> (SomeANN::*oracle_f)(const VectorXd&);
tuple<double, VectorXd> f(const VectorXd& theta);
};
template <>
inline tuple<double, VectorXd> SomeANN<kConjugateGradient>::f(const VectorXd& theta) {
double f = 0.0;
VectorXd df;
return make_tuple(f, df);
}
// ridge solver using conjugate gradient
template <>
inline void SomeANN<kConjugateGradient>::ridge_solve(const VectorXd& Y) {
ConjugateGradient<BeginSpace, VectorXd, SomeANN::oracle_f> optimizer;
// ...
optimizer.search(BeginSpace(Y.rows()), boost::bind(&SomeANN::f, this, _1));
}
然后我得到错误:
some_ann.h:163:84: error: no matching function for call to 'ConjugateGradient<BeginSpace, Eigen::Matrix<double, -0x00000000000000001, 1>, boost::tuples::tuple<double, Eigen::Matrix<double, -0x00000000000000001, 1> > (SomeANN<(Minimizer)1u>::*)(const Eigen::Matrix<double, -0x00000000000000001, 1>&)>::search(BeginSpace, boost::_bi::bind_t<boost::tuples::tuple<double, Eigen::Matrix<double, -0x00000000000000001, 1> >, boost::_mfi::mf1<boost::tuples::tuple<double, Eigen::Matrix<double, -0x00000000000000001, 1> >, SomeANN<(Minimizer)1u>, const Eigen::Matrix<double, -0x00000000000000001, 1>&>, boost::_bi::list2<boost::_bi::value<SomeANN<(Minimizer)1u>*>, boost::arg<1> > >)'
conjugate_gradient.h:67:2: error: must use '.*' or '->*' to call pointer-to-member function in 'f (...)', e.g. '(... ->* f) (...)'
conjugate_gradient.h:84:3: error: must use '.*' or '->*' to call pointer-to-member function in 'f (...)', e.g. '(... ->* f) (...)'
conjugate_gradient.h:111:5: error: must use '.*' or '->*' to call pointer-to-member function in 'f (...)', e.g. '(... ->* f) (...)'
conjugate_gradient.h:153:4: error: must use '.*' or '->*' to call pointer-to-member function in 'f (...)', e.g. '(... ->* f) (...)'
make[2]: *** [CMakeFiles/some_ann_library.dir/main/cpp/some_ann.cc.o] Error 1
make[1]: *** [CMakeFiles/some_ann_library.dir/all] Error 2
make: *** [all] Error 2
不要改变搜索,传递一个绑定表达式:
auto& solution = cg.search(space, std::bind(
&MyType::member_function, &myInstance, std::placeholders::_1));
相关文章:
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针