是否有可能不继承boost ::运算符,但仍然使用它?

时间:2017-02-14 16:48:17

标签: c++ templates inheritance boost operators

根据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_comparable1boost::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;
    }
};

1 个答案:

答案 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) }; 并将宏调用放在类之外。)

除了添加构造函数和编写宏之外,另一种选择是希望<=>能够实现,然后等待几年才能使用它。