包装谓词函子
我想知道有关谓词函子包装的约定和最佳实践。例如,给定一个像这样的类:
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 声明之后的头文件中
- 嵌套在 Timer 中(即,引用变为
Timer::TimerNameIs
) - 嵌套在 TimerVec 中(当前是唯一用户)
- 在实现之前的匿名命名空间中TimerVec::findByName(又是唯一使用它的地方)
虽然其中任何一个都足够了,但我更喜欢#2,但这不是我见过的做法。是否有任何支持特定选项的具体原因?
I'm wondering about conventions and best practices regarding the packaging of predicate functors. For example, given a class like:
class Timer
{
public:
Timer(const std::string& name, int interval);
bool nameIs(const std::string& name) const;
private:
std::string name_;
int interval_;
};
that is (in one case) used in class TimerVec
:
class TimerVec
{
public:
typedef std::vector<Timer>::iterator iterator;``
<... ctors, etc ...>
iterator findByName(const std::string& name);
private:
std::vector<Timer> timers_;
};
and has a predicate functor like:
class TimerNameIs
{
public:
TimerNameIs(const std::string& name) : name_(name) {}
bool operator()(const Timer& t) { return t.nameIs(name_); }
private:
const std::string& name_;
};
I can think of a number of places to put the functor code, some being:
- In the header file immediately following the declaration of Timer
- Nested inside Timer (i.e. so the ref becomes
Timer::TimerNameIs
) - Nested inside TimerVec (currently the only user)
- In an anonymous namespace ahead of the implementation for
TimerVec::findByName
(again the only place it's used)
While any of these would be adequate I'm rather drawn to #2, but it's not something I've ever seen done. Are there any concrete reasons favoring a particular option?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这有待商榷。我更喜欢创建一个嵌套类。这样,仅适用于特定类型对象的函子就在该对象内的命名空间范围内。
我通常还将谓词命名为
match_xxx
,其中xxx
是我要匹配的参数。也就是说:
...这样使用:
我更喜欢这种方法,因为 6 个月后查看此代码时,
Timer::match_name("Flibbidy")
的语义非常清晰。我还小心地从
std::unary_function
派生我的函子(尽管我上面的派生可能会将参数颠倒)。This is open to debate. I prefer to create a nested class. This way a functor that is intended only to work with a particular type of object is namespace-scoped within that object.
I also generally name the predicate
match_xxx
wherexxx
is the parameter I'm matching on.To wit:
...which is utilized thusly:
I prefer this method because the semantics of
Timer::match_name("Flibbidy")
are exceedingly clear when looking at this code 6 months later.I also am careful to derive my functor from
std::unary_function
(although my derivation above might have the parameters reversed).就我个人而言,在它自己的头文件和 cpp 文件中。在
TimerNameIs
头文件中使用#include "Timer.h"
:这样做可以将 Timer 和 TimerNameIs 相互隔离。
Me, personally, in it's own header and cpp files. Using
#include "Timer.h"
in theTimerNameIs
header file:Doing this, you isolate Timer and TimerNameIs from one to the other.