在网上我发现了一些关于函数对象(callees)的例子,但他们没有演示如何将它们用作回调函数(调用它们,调用者)的参数,而仅仅是它在使用sort时的使用方式或for_each。因此,我自己做了一个:
class CBase
{
public:
virtual int operator()(int a, int b)
{
return 10;
}
};
class CSmaller: public CBase
{
public:
int operator()(int a, int b)
{
return a < b;
}
int Compute(int a, int b)
{
return a < b;
}
};
class CLarger: public CBase
{
public:
int operator()(int a, int b)
{
return a > b;
}
int Compute(int a, int b)
{
return a > b;
}
};
int caller(CBase &f, int x0, int x1)
{
return f(x0,x1);
}
int main()
{
CLarger callee1; /*this callee is being called by caller*/
CSmaller callee2; /*idem*/
int q=caller(callee1,0,1);
int z=caller(callee2,0,1);
printf("%d\n",q);
printf("%d\n",z);
}
这些STL函数对象(比如更少)是以这种方式实现的(因为它通常只有一般名称/类'模板')?即,他们(CLarger和CSmaller)是否有一个关系/共同的安慰者,每个类都有一个扩展的虚函数,或者它们也可以是一些通用函数对象(只要它们用两个参数实现()运算符)?像这样(虽然未经过测试):
template<class F>
float integrate(const F &f,float x0,float x1)
{
..f(x)..;
}
float derive(const F &f,float x0,float x1)
{
..f(x)..;
}
class CSquare
{
public:
float operator()(float x)
{
return x*x;
}
};
class CTwoX
{
public:
float operator()(float x)
{
return 2*x;
}
};
如果这是正确的方法,那么这些非相关类将如何以非STL方式实现?我知道使用模板并保持底层机制(以这种方式它们是相关的)但只有类型是不同的。但是需要这种关系(即同一个安慰者)吗?
在函数对象中使用重载()仅仅是为了方便吗?因为我也可以使用CLarger的Compute。我还可以将这些分离的类(使用virtual作为其不同的功能)合并到类CCompute中,例如,成员更大和更小。顺便说一句,我想我也可以将派生和集成在一个类中。我的想法是否有意义,或者我的想法是否与STL理论相矛盾?
答案 0 :(得分:1)
您可以采用任何一种方式:继承或模板。但是,两者都不是必需的。 STL函数是模板化的,这意味着只要表达式f(x)
按需要工作,您就可以传递f
的任何内容(例如函数指针,仿函数 - 你称之为被调用者)。
注意:f(x)
只是一个例子,参数的确切数量取决于所使用的特定STL函数。
继承的优点是您可以将公共行为封装在基类中,并在运行时根据实际类型执行。
模板的优点是你可以使用任何类型(基于模板参数) - 所以虽然你可以在每个类中重载operator()
,但创建一个可以更容易的模板类可能更容易hanlde每种类型(如果某些类型需要特殊处理,则使用模板专业化)
请注意,使用模板时,会为每个实际模板参数类型组合
创建不同的类型答案 1 :(得分:0)
接受函数参数的STL算法(例如,谓词)通常不关心如何创建参数,只要它匹配“类似函数”接口;它需要做的就是使用模板参数推导来推断类型
template< typename FwdIter, typename Pred >
FwdIter find_if( FwdIter first, FwdIter last, Pred pred );
/* .. etc ... */
bool is_equal_to_one(int n) { return n == 1; }
int main()
{
std::vector<int> foo;
std::vector<int>::const_iterator iter;
iter = std::find_if( foo.begin(), foo.end(), is_equal_to_one );
}
实现Pred
类型有太多不同的可能方式来执行任何其他方式(函数,仿函数,std ::函数......)。 find_if函数将依赖Pred
作为与bool (*FwdIt)