如何将谓词作为函数参数传递
我有一个类 CMyVector
,它保存指向 CMyClass
对象的指针向量,并且我有几个“查找”函数来根据不同的标准查找元素。例如,我有:
CMyClass* CMyVector::FindByX(int X);
CMyClass* CMyVector::FindByString(const CString& str);
CMyClass* CMyVector::FindBySomeOtherClass(CSomeOtherClass* ptr);
// Other find functions...
首先,它们被实现为循环,遍历向量,寻找与 X、str、ptr 或其他内容匹配的元素。所以我创建了谓词,就像这样:
class IsSameX:public unary_function<CMyClass*, bool>
{
int num;
public:
IsSameX(int n):num(n){}
bool operator()(CMyClass* obj) const
{
return (obj != NULL && (obj->X() == num));
}
};
最后以一堆函数结束,它们看起来都像这样:
CMyClass* CMyVector::FindByX( int x )
{
CMyVector::iterator it = find_if(vec.begin(), vec.end(), IsSameX(x));
if (it != vec.end())
{
return *it;
}
return NULL;
}
除了被调用的谓词之外,它们看起来都一样,所以我考虑简化更多,并创建了一个功能如下:
CMyClass* CMyVector::Find( ThisIsWhatIDontKnow Predicate)
{
CMyVector::iterator it = find_if(vec.begin(), vec.end(), Predicate);
if (it != vec.end())
{
return *it;
}
return NULL;
}
并执行:
CMyClass* CMyVector::FindByX( int x )
{
return Find(IsSameX(x));
}
等等。
所以我的问题是:我应该如何声明我的 Find 函数以便我可以将谓词传递给它?我尝试了多种方法,但到目前为止还没有运气。
I have a class CMyVector
which holds a vector of pointers to CMyClass
objects and I have several "find" functions to find elements according to differente criteria. So for example, I have:
CMyClass* CMyVector::FindByX(int X);
CMyClass* CMyVector::FindByString(const CString& str);
CMyClass* CMyVector::FindBySomeOtherClass(CSomeOtherClass* ptr);
// Other find functions...
At first, they were implemented as loops, traversing the vector, looking for the element that matches X, str, ptr or whatever. So I've created predicates, like this one:
class IsSameX:public unary_function<CMyClass*, bool>
{
int num;
public:
IsSameX(int n):num(n){}
bool operator()(CMyClass* obj) const
{
return (obj != NULL && (obj->X() == num));
}
};
And ended with a bunch of functions which all look like this:
CMyClass* CMyVector::FindByX( int x )
{
CMyVector::iterator it = find_if(vec.begin(), vec.end(), IsSameX(x));
if (it != vec.end())
{
return *it;
}
return NULL;
}
They all look the same, except for the predicate that is called, so I've thought of simplifying more, and created a function like this one:
CMyClass* CMyVector::Find( ThisIsWhatIDontKnow Predicate)
{
CMyVector::iterator it = find_if(vec.begin(), vec.end(), Predicate);
if (it != vec.end())
{
return *it;
}
return NULL;
}
And do:
CMyClass* CMyVector::FindByX( int x )
{
return Find(IsSameX(x));
}
And so on.
So my question is: How should I declare my Find
function so I can pass it my predicates? I've tried several ways, but with no luck so far.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用模板接受您需要的任何类型
您也可以始终使用 std::function (c++11)
就我个人而言,我更喜欢第一个,因为编译器可能更容易优化,因为间接性较少。如果调用是唯一的,它可能会被内联。
编辑:还值得注意的是,如果使用模板化选项,则必须在头文件中提供实现,这可能会很痛苦。而 std::function 可以与所有其他实现一起存在于源 (.cpp) 文件中。
use template to take in whatever ever type you need
You could alway also use std::function (c++11)
Personally I prefer the top one, because it will probably be easier for the compiler to optimize as there is less indirection. and if the call is unique it might get inlined.
EDIT: It is also worth noting that if go you with the templated option, you will have to provide the implementation in the header file, this can be a pain. Whereas the std::function can live in the source (.cpp) file with all the other implementations.