简体   繁体   English

是否可以不继承boost :: operators但仍然使用它呢?

[英]Is it possible not to inherit from boost::operators, but still use it?

According to boost documentation - proper usage of boost::operators is to derive from it: 根据boost文档 -boost :: operators的正确用法是从中得出的:

class A : boost::operators<A>
{
public:
    bool operator < (const A&) const { return false; }
};

Now, I can use > and <= and >= because all of these operators can be implemented with < , see code snippet from boost: 现在,我可以使用><=>=因为所有这些运算符都可以通过<来实现,请参见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); }
};

And finally less_than_comparable1 is one of boost::operators base class. 最后, less_than_comparable1boost::operators基类之一。

PROBLEM: But adding such inheritance is not always convenient. 问题:但是添加这样的继承并不总是很方便。 Eg this inheritance means I have to add constructor(s) to some structs, otherwise all old code, such as A{1} stops compiling: 例如,这种继承意味着我必须向某些结构添加构造函数,否则所有旧代码(例如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&);

I tried several ways: inner class, static members of boost::operators<A> but it seems that only inheritance works. 我尝试了几种方法:内部类, boost::operators<A>静态成员,但似乎只有继承有效。


I accept an answer that shows the way how to use boost::operators without inheritance. 我接受一个答案,该答案显示了如何在不继承的情况下使用boost :: operators的方式。
I can also accept an answer, that explains why this inheritance is needed. 我也可以接受一个答案,它解释了为什么需要这种继承。


Ok, let's simplify a little this example, why I need inheritance in this very example below to get operator > from operator < ? 好的,让我们简化一下这个示例,为什么我在下面的这个示例中需要继承才能从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;
    }
}

Nothing else seems to work, eg this way does not work: 似乎没有其他工作,例如,这种方式行不通:

struct A
{
    GtOperator<A> dummy;

    bool operator < (const A&) const
    {
        return false;
    }
};

Is it possible not to inherit from boost::operators , but still use it? 是否可以不继承boost::operators ,但仍要使用它?

No, basically. 不,基本上。 It's intended to be inherited from. 它是要继承的。 The reason it works is because argument-dependent lookup will only look for friend functions and function templates in associated classes ([basic.lookup.argdep]/4) - which are going to be A and A 's base classes. 它起作用的原因是因为依赖于参数的查找将仅在关联的类 ([basic.lookup.argdep] / 4)中查找朋友函数和函数模板,它们将是AA的基类。 If boost::operators<A> isn't a base class of A , its friend functions won't be found by name lookup. 如果boost::operators<A>不是A的基类,则不会通过名称查找找到其friend功能。

Even with new aggregate initialization rules in C++17, A{1,2} would break because you'd have to write A{{},1,2} . 即使使用C ++ 17中的新聚合初始化规则, A{1,2}也会因为您必须编写A{{},1,2}而中断。

Your best bet is probably to write a macro that functions as a mixin that effectively accomplishes the same thing. 最好的选择是编写一个宏,充当可有效完成同一件事的混合功能。 So the ordering ones would be: 因此订购的将是:

#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)
};

Yes, that kind of sucks. 是的,那太烂了。 (Also these could be defined as non-member functions as well, just drop the friend and put the macro invocation outside of the class). (也可以将这些也定义为非成员函数,只需删除friend并将宏调用放在类之外)。

The other alternative, besides adding constructors and writing macros, is to hope that <=> comes to fruition and then wait a few years to be able to use it. 除了添加构造函数和编写宏之外,另一种替代方法是希望<=>成为现实,然后等待几年才能使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM