我一直在整理一些旧的C ++代码。
我使用几个宏减少了运算符重载函数的页面:
.HPP
// for context, Long and Object wrap respective Python primitives
class Long: public Object
{...};
#define OPS( A, B ) \
bool operator == ( A, B ); \
bool operator != ( A, B ); \
bool operator > ( A, B ); \
bool operator < ( A, B ); \
bool operator >= ( A, B ); \
bool operator <= ( A, B );
#define UNI( A ) \
OPS( A, A )
#define BI_( A, B ) \
OPS( A, B ) \
OPS( B, A )
UNI( const Long& )
BI_( const Long& , int )
BI_( const Long& , long )
UNI( const Float& )
BI_( const Float& , double )
#undef BI_
#undef UNI
#undef OPS
#undef OP
的.cpp
#define OP( op, l, r, cmpL, cmpR ) \
bool operator op( l, r ) { return cmpL op cmpR; }
#define OPS( ... ) \
OP( != , ##__VA_ARGS__ ) \
OP( == , ##__VA_ARGS__ ) \
OP( > , ##__VA_ARGS__ ) \
OP( >= , ##__VA_ARGS__ ) \
OP( < , ##__VA_ARGS__ ) \
OP( <= , ##__VA_ARGS__ )
#define BI_( a, b, convA, convB ) \
OPS( a, b, convA, convB ) \
OPS( b, a, convB, convA )
OPS( const Long& a, const Long& b , a.as_long() , b.as_long() )
BI_( const Long& a, int b , a.as_long() , b )
BI_( const Long& a, long b , a.as_long() , b )
OPS( const Float& a, const Float& b , a.as_double() , b.as_double() )
BI_( const Float& a, double b , a.as_double() , b )
#undef BI_
#undef OPS
#undef OP
它仍然感觉不太正确。
它将类扩展到三个不同的位置:类声明本身,稍后在同一标头中的运算符声明,然后在单独的.cxx文件中实际定义。
在C ++ 11中有更简洁的方法来实现这些运算符吗?
答案 0 :(得分:8)
为什么不使用CRTP基类来提供所有运算符?
template<typename C, typename T>
struct ops_base
{
friend bool operator==(const ops_base& l, const ops_base& r)
{
const C& cl = static_cast<const C&>(l);
const C& cr = static_cast<const C&>(r);
return (caster<C, T>::cast(cl) == caster<C, T>::cast(cr));
}
friend bool operator==(const ops_base& l, T r)
{
const C& cl = static_cast<const C&>(l);
return (caster<C, T>::cast(cl) == r);
}
friend bool operator==(T l, const ops_base& r)
{
const C& cr = static_cast<const C&>(r);
return (l == caster<C, T>::cast(cr));
}
friend bool operator!=(const ops_base& l, const ops_base& r)
{ return !(l == r); }
friend bool operator!=(const ops_base& l, T r)
{ return !(l == r); }
friend bool operator!=(T l, const ops_base& r)
{ return !(l == r); }
friend bool operator<(const ops_base& l, const ops_base& r)
{
const C& cl = static_cast<const C&>(l);
const C& cr = static_cast<const C&>(r);
return (caster<C, T>::cast(cl) < caster<C, T>::cast(cr));
}
friend bool operator<(const ops_base& l, T r)
{
const C& cl = static_cast<const C&>(l);
return (caster<C, T>::cast(cl) < r);
}
friend bool operator<(T l, const ops_base& r)
{
const C& cr = static_cast<const C&>(r);
return (l < caster<C, T>::cast(cr));
}
friend bool operator>(const ops_base& l, const ops_base& r)
{
const C& cl = static_cast<const C&>(l);
const C& cr = static_cast<const C&>(r);
return (caster<C, T>::cast(cl) > caster<C, T>::cast(cr));
}
friend bool operator>(const ops_base& l, T r)
{
const C& cl = static_cast<const C&>(l);
return (caster<C, T>::cast(cl) > r);
}
friend bool operator>(T l, const ops_base& r)
{
const C& cr = static_cast<const C&>(r);
return (l > caster<C, T>::cast(cr));
}
friend bool operator<=(const ops_base& l, const ops_base& r)
{ return !(l > r); }
friend bool operator<=(const ops_base& l, T r)
{ return !(l > r); }
friend bool operator<=(T l, const ops_base& r)
{ return !(l > r); }
friend bool operator>=(const ops_base& l, const ops_base& r)
{ return !(l < r); }
friend bool operator>=(const ops_base& l, T r)
{ return !(l < r); }
friend bool operator>=(T l, const ops_base& r)
{ return !(l < r); }
};
然后像这样使用它:
struct Long : ops_base<Long, long>
{
Long(long val) : value_(val) { }
long as_long() const { return value_; }
private:
long value_;
};
struct Float : ops_base<Float, double>
{
Float(double val) : value_(val) { }
double as_double() const { return value_; }
private:
double value_;
};
在ideone上运行示例。