C++关系运算符生成器
C++ relational operators generator
一旦定义了<
运算符,就可以估计其他关系运算符的行为。我正在尝试为我的类实现一种方法。
我想要的是只定义<
和其他要隐式默认的运算符。到目前为止,我得到的是这个设计,我将在下面详细介绍:
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; }
感谢您的建议,这里有一个代码工作
我通常会用从Robert Martin那里学到的技巧来做这件事。我有一个模板类:
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;
}
};
需要运算符的类由此派生:
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;
};
(我的实现实际上有点复杂,因为使用一些简单的元编程来调用isEqual
,而不是compare
,如果该函数存在的话。(
编辑:
重读你的问题:这基本上就是你在做的事情,这几乎是这类事情的标准习语。我更喜欢使用像compare
这样的命名函数,但这只是我个人的偏好。然而,处理isEqual
的元编程技巧值得一试:这意味着你可以对只支持相等的类型使用同一个类;当编译器试图实例化operator<=
时,你会遇到一个错误,但除非有人使用它,否则编译器不会尝试实例化它。通常情况下,isEqual
的实现效率比compare
高得多。
编辑2:
值得一提的是:我系统地做这件事。我也有CCD_ 14(例如根据CCD_,MixedTypeArithmeticOperators
(与上面类似,但有两个类型,T1
(它是基类(和T2
;它提供了运算符的所有组合(。和STLIteratorOperators
,实现STL迭代器基于更合理、更容易实现(基本上,使用isEqual
实现GoF迭代器函数(。它们节省了很多样板。
编辑3:
最后:我只是查看了工具包中的实际代码。有条件地支持isEqual
甚至比我记得:上面的模板类有一个公共成员:
bool isEqual( T const& other ) const
{
return static_cast< T const* >( this )->compare( other ) == 0;
}
而operator==
和operator!=
只是使用了isEqual
,没有涉及模板元编程。如果派生类定义了一个isEqual
,它隐藏了这个CCD_26并被使用。如果不,这个习惯了。
朋友不是继承的,所以这个想法行不通。然而,您可以巧妙地使用宏,例如:
#define GEN(X)
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); }
您可以使用作为:
class Foo
{
...
GEN(foo)
};
- 在 c++ 中对字符串进行操作的关系运算符无法按预期工作
- 为什么在C++中使用关系运算符创建的模板函数不能对字符串正常工作?
- 当关系运算符的含义相同时,为什么结果不同?
- C++使用关系运算符比较字符串
- 阐明关系运算符重载的概念(需要调试帮助)
- 迭代器关系运算符出错(带单独链接和迭代器的自定义哈希表)
- 当我有两个对象时<<如何重载运算符?(有关系)
- 为什么赋值运算符和相等运算符之间没有 1:1 的关系?
- 重载运算符<关系C++
- C++使用 shared_ptr 但调用了对象的关系运算符?
- C++ 字符 - 关系运算符
- 使用关系运算符比较指针意味着什么
- C++ 如何重载关系运算符以检查两个对象是否相同
- 枚举类的关系运算符重载
- C++ STL 关系运算符如何比较堆栈
- 为什么指针类型的内置关系运算符不生成C++的总顺序?
- ostream 插入运算符与其非成员重载之间的关系
- 字符串类关系运算符重载
- 与关系运算符的字符串比较(长度不同)
- 为两个类定义重载的强制转换运算符,这两个类之间具有循环依赖关系