根据boost documentation - 正确使用boost ::运算符来源于它:
class A : boost::operators<A>
{
public:
bool operator < (const A&) const { return false; }
};
现在,我可以使用>
和<=
以及>=
,因为所有这些运算符都可以使用<
实现,请参阅boost中的代码段:
template <class T, class B = operators_detail::empty_base<T> >
struct less_than_comparable1 : B
{
friend bool operator>(const T& x, const T& y) { return y < x; }
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
};
最后less_than_comparable1
是boost::operators
基类之一。
问题:
但是添加这样的继承并不总是方便的。例如。这种继承意味着我必须将构造函数添加到某些结构中,否则所有旧代码(例如A{1}
)都会停止编译:
struct A : boost::operators<A>
{
A() = default;
A(int a, int b = 0) : a(a), b(b) {}
int a;
int b;
};
bool operator < (const A&, const A&);
我尝试了几种方法:内部类,boost::operators<A>
的静态成员,但似乎只有继承有效。
我接受一个答案,说明如何使用不带继承的boost ::运算符 我也可以接受一个答案,这解释了为什么需要这种继承。
好的,让我们简化一下这个例子,为什么我需要在下面这个例子中继承才能从operator >
获得operator <
?
template <typename A>
struct GtOperator
{
friend bool operator > (const A& l, const A& r)
{
return r < l;
}
};
struct A : private GtOperator<A>
{
bool operator < (const A&) const
{
return false;
}
};
int main() {
if (A{} > A{})
{
return -1;
}
}
似乎没有其他工作,例如这种方式不起作用:
struct A
{
GtOperator<A> dummy;
bool operator < (const A&) const
{
return false;
}
};
答案 0 :(得分:2)
是否有可能不继承
boost::operators
,但仍然使用它?
不,基本上。它的目的是继承自。它起作用的原因是因为依赖于参数的查找只会在关联类([basic.lookup.argdep] / 4)中查找友元函数和函数模板 - 它们将是{{1} }和A
的基类。如果A
不是boost::operators<A>
的基类,则名称查找将找不到其A
函数。
即使使用C ++ 17中的新聚合初始化规则,friend
也会中断,因为您必须编写A{1,2}
。
你最好的选择可能是编写一个宏作为mixin,有效地完成同样的事情。所以订购的是:
A{{},1,2}
是的,那种糟透了。 (这些也可以定义为非成员函数,只需删除#define LESS_THAN_COMPARABLE(T) \
friend bool operator>(const T& x, const T& y) { return y < x; } \
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); } \
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
class A
{
public:
bool operator < (const A&) const { return false; }
LESS_THAN_COMPARABLE(A)
};
并将宏调用放在类之外。)
除了添加构造函数和编写宏之外,另一种选择是希望<=>
能够实现,然后等待几年才能使用它。