我想知道关于谓词仿函数打包的约定和最佳实践。例如,给定一个类:
class Timer
{
public:
Timer(const std::string& name, int interval);
bool nameIs(const std::string& name) const;
private:
std::string name_;
int interval_;
};
在TimerVec
课程中使用的(在一个案例中):
class TimerVec
{
public:
typedef std::vector<Timer>::iterator iterator;``
<... ctors, etc ...>
iterator findByName(const std::string& name);
private:
std::vector<Timer> timers_;
};
并且有一个谓词函子,如:
class TimerNameIs
{
public:
TimerNameIs(const std::string& name) : name_(name) {}
bool operator()(const Timer& t) { return t.nameIs(name_); }
private:
const std::string& name_;
};
我可以想到一些放置仿函数代码的地方,其中一些是:
Timer::TimerNameIs
)TimerVec::findByName
的实施之前的匿名命名空间中(同样是唯一使用它的地方)虽然其中任何一个都足够了,但我更倾向于#2,但这不是我见过的。是否有任何具体的理由支持特定的选择?
答案 0 :(得分:1)
我个人而言,在它自己的标题和cpp文件中。在#include "Timer.h"
标头文件中使用TimerNameIs
:
#include "Timer.h"
#include <string>
class TimerNameIs
{
public:
TimerNameIs(const std::string& name) : name_(name) {}
bool operator()(const Timer& t) { return t.nameIs(name_); }
private:
const std::string& name_;
};
这样做,可以将Timer和TimerNameIs从一个隔离到另一个。
答案 1 :(得分:1)
这是有争议的。我更喜欢创建一个嵌套类。这样,仅用于处理特定类型对象的仿函数在该对象中具有命名空间作用。
我通常也会为谓词match_xxx
命名,其中xxx
是我匹配的参数。
即便:
class Timer
{
// ...
public:
class match_name : public std::unary_function<Timer, bool>
{
public:
match_name(const std::string& name) : name_(name) {}
bool operator()(const Timer& t) { return t.nameIs(name_); }
private:
const std::string& name_;
};
};
...因此得到利用:
std::find_if( v.begin(), v.end(), Timer::match_name("Flibbidy") );
我更喜欢这种方法,因为在{6}之后查看此代码时,Timer::match_name("Flibbidy")
的语义非常清晰。
我也很谨慎从std::unary_function
派生我的仿函数(尽管我上面的推导可能反转了参数)。