【发布时间】:2014-04-30 12:57:41
【问题描述】:
一旦定义了< 运算符,您就可以估计其余关系运算符的行为方式。我正在尝试为我的课程实现一种方法。
我想要的是只定义 < 和其他隐式默认的运算符。到目前为止我得到的是这个设计,我将在下面详细说明:
template<typename T>
struct relational
{
friend bool operator> (T const &lhs, T const &rhs) { return rhs < lhs; }
friend bool operator==(T const &lhs, T const &rhs) { return !(lhs < rhs || lhs > rhs); }
friend bool operator!=(T const &lhs, T const &rhs) { return !(rhs == lhs); }
friend bool operator<=(T const &lhs, T const &rhs) { return !(rhs < lhs); }
friend bool operator>=(T const &lhs, T const &rhs) { return !(lhs < rhs); }
};
因此,对于实现 < 运算符的类,它只需要从 relational 继承即可默认其余运算符。
struct foo : relational<foo>
{
// implement < operator here
};
- 有没有更好的设计替代品?
-
这段代码中有定时炸弹吗?我假设如果用户想要为其中一个运算符定义自定义实现,重载决议将启动并选择非模板(用户定义)实现。如果不是这种情况(或者我会遇到从
relational继承的类模板的问题),我应该像这样实现relational中的运算符吗?// inside the relational struct friend bool operator>(relational const &lhs, relational const &rhs) { // functions that involve implicit conversion are less favourable in overload resolution return (T const&)rhs < (T const&)lhs; }
感谢您的建议,这里是demo of the code working
【问题讨论】:
-
您应该注意,朋友关系不会被继承。我不知道这是否会在某个时候打击你。
-
旁注:rhs 表示“右手边”,lhs 表示“左手边”。看来您的函数参数是反向命名的。此外,虽然根据
operator <定义operator ==在数学上可能很有趣,但它很可能对性能不友好,因为您调用operator <两次,而实际操作可能与单个operator ==非常相似。跨度> -
1.您部分复制了Boost.Operators 和
std::rel_ops。 2. 如果您允许 2 个原始操作,您会发现更多客户端:<和==。在某些情况下,<的排序不是全部,即!(a<b) && !(a>b) && a!=b。 -
@Angew 客户端只会是你自己写的类(或者知道这个类存在的人写的),所以你可以走得更远,使用命名函数。为什么要特权
<? -
@JamesKanze 因为这就是
std::rel_ops所做的:-) 但你是对的,当然没有根本原因,正如你在回答中所证明的那样(我已经赞成)。跨度>