【问题标题】:Is it possible that the pre-processor can change the sign for operator overloading function?预处理器是否可以更改运算符重载函数的符号?
【发布时间】:2020-05-15 16:05:47
【问题描述】:

我只想编写一个运算符重载函数,但它可以执行 ==,!=, 或 >=。 我们是否可以使用预处理器来更改函数的符号?像这样的

class A{
    private:
         int b;
         //some code
    public:
         #define macro(sign) sign
         bool operator macro(sign)(const A& obj){
              return (b macro(sign) obj.b)
         }  
}

对不起,我知道做这样的事情是完全不可能的。但我只是好奇我是否可以编写一个泛型运算符重载函数。

【问题讨论】:

  • 不要永远使用宏,除非它是唯一可能的选择(这很少见)。
  • 你让我在“不要永远使用宏...”。

标签: c++ generics operator-overloading


【解决方案1】:

C++20 有一个 spaceship 运算符,可以免费为您提供所有这些内容:

auto operator<=>(const A& obj) const = default;

如果您的类更复杂以至于无法进行成员比较,则需要同时定义operator&lt;=&gt;(返回one of the _ordering types)和operator==,因为使用&lt;=&gt; 进行非默认相等很容易对于包含字符串或向量之类的任何类型,都会陷入性能陷阱。其他比较将被重写以使用这两个运算符。

这是full example

#include <cassert>
#include <compare>

struct A {
    int b;

    auto operator<=>(const A&) const = default;
};

struct B {
    int b;

    // This could return auto but this is an example.
    std::strong_ordering operator<=>(const B& other) const {
        return other.b <=> b;
    }

    bool operator==(const B& other) const {
        return b == other.b;
    }
};

int main() {
    A a1{1}, a2{2};

    assert(a1 < a2);
    assert(a2 >= a1);
    assert(a1 != a2);

    B b1{1}, b2{2};

    assert(b2 < b1);
    assert(b1 >= b2);
    assert(b1 != b2);
}

【讨论】:

  • 快速说明,从 llvm 10 开始,C++20 的标志现在是 c++20 而不是 c++2a。你会得到不同的结果(不是这段代码),至少我在玩概念时是这样。
  • @sweenish,有趣的是它不是别名标志,但是谢谢,我一直想更新我用来生成这些选项的热字串。
【解决方案2】:

很高兴你注意到它们的逻辑都非常相似——好眼光!

实际上只写一个运算符很常见,通常是operator&lt;。然后我们可以在其他任何地方使用它。所以你的实现可能看起来像:

class A {
    bool operator<(const A& rhs) const {
        // Custom comparison logic here...
    }

    bool operator>(const A& rhs) const { return rhs < *this; }
    bool operator<=(const A& rhs) const { return !(rhs < *this); }
    bool operator>=(const A& rhs) const { return !(*this < rhs); }
    bool operator==(const A& rhs) const { return !(*this < rhs) && !(rhs < *this); }
    bool operator!=(const A& rhs) const { return (*this < rhs) || (rhs < *this); }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2014-11-04
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    相关资源
    最近更新 更多