定义<运算符后,您就可以估计其余关系运算符的行为方式。我正在尝试为我的课程实现一种方法。
我想要的是仅定义<和其余的运算符隐式默认。到目前为止我所得到的是这个设计,我将在下面进一步详细说明:
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); }
};
Run Code Online (Sandbox Code Playgroud)
因此,对于实现该运算符的类,<只需继承relational即可使其余运算符默认。
struct foo : relational<foo>
{
// implement < operator here
};
Run Code Online (Sandbox Code Playgroud)
这段代码里有定时炸弹吗?我假设如果用户想要为其中一个运算符定义自定义实现,重载决策将启动并选择非模板(用户定义)实现。如果情况并非如此(或者我会遇到继承自 的类模板的问题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;
}
Run Code Online (Sandbox Code Playgroud)感谢您的建议,这是代码工作的演示
我通常使用从罗伯特·马丁那里学到的技巧来做到这一点。我有一个模板类:
template <typename T>
class ComparisonOperators
{
protected:
~ComparisonOperators() {}
public:
friend bool operator==( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) == 0;
}
friend bool operator!=( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) != 0;
}
friend bool operator<( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) < 0;
}
friend bool operator<=( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) <= 0;
}
friend bool operator>( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) > 0;
}
friend bool operator>=( T const& lhs, T const& rhs )
{
return lhs.compare( rhs ) >= 0;
}
};
Run Code Online (Sandbox Code Playgroud)
需要运算符的类派生于此:
class Toto : public ComparisonOperators<Toto>
{
// ...
public:
// returns value < 0, == 0 or >0, according to
// whether this is <, == or > other.
int compare( Toto const& other ) const;
};
Run Code Online (Sandbox Code Playgroud)
(我的实现实际上有点复杂,因为它使用一些简单的元编程来调用isEqual,而不是
compare,如果该函数存在。)
编辑:
重新阅读你的问题:这基本上就是你正在做的事情,而且这几乎是这类事情的标准习惯用法。我更喜欢使用诸如 之类的命名函数compare,但这只是个人喜好。然而,处理 的元编程技巧isEqual是值得费心的:这意味着您可以对仅支持相等的类型使用相同的类;当编译器尝试实例化 eg 时,您会收到错误operator<=,但除非有人使用它,否则编译器不会尝试实例化它。通常情况下,它的isEqual实施效率比compare.
编辑2:
对于它的价值:我系统地这样做。我也有
ArithmeticOperators(定义例如+)+=,
MixedTypeArithmeticOperators(像上面一样,但是有两种类型,T1它是基类,并且T2它提供了所有运算符的组合)。和
STLIteratorOperators,它基于更合理且更容易实现的东西(基本上是带有函数的 GoF 迭代器isEqual
)实现了 STL 迭代器接口。他们节省了大量的样板文件。
编辑3:
最后:我只是查看了工具包中的实际代码。有条件支持isEqual比我记忆中的还要简单:上面的模板类有一个公共成员:
bool isEqual( T const& other ) const
{
return static_cast< T const* >( this )->compare( other ) == 0;
}
Run Code Online (Sandbox Code Playgroud)
并且operator==只需operator!=使用isEqual,不涉及模板元编程。如果派生类定义了一个isEqual,它会隐藏这个并被使用。如果没有,就用这个。
| 归档时间: |
|
| 查看次数: |
1561 次 |
| 最近记录: |