相互重载operator ++前缀/后缀?

时间:2010-07-14 00:28:02

标签: c++ operator-overloading increment

我有一个问题可能已经回答了9000多次,但我真的不知道如何说出来,这就是我要尝试的。

我在一些C ++书籍和教程中看到,在定义具有可迭代值(可递增)语义的自己的类时,可以为它重载operator++(我将在这里说明我所有的' d guess也适用于operator--。这样做的标准方法似乎是:

class MyClass {
    public:
    MyClass& operator++ () {
        increment_somehow();
        return *this;
        }
    ....
    };

increment_somehow()井...... 以某种方式递增对象的值。

然后,可以用以下方式定义operator++的后缀版本:

MyClass operator++ (MyClass& it, int dummy) {
    MyClass copy(it);
    ++it;
    return copy;
    }

一切都很好和花花公子(我认为我的成语是正确的),但问题是,为每个定义operator++的类做所有这些很快变得烦人和冗长,所以我想我可以利用我最近在重载运算符时学到的技巧。也就是说,利用<utility>标题和我昨天发现的名为rel_ops的设施(我只是在四年离开之后回到C ++。 ..):

class MyClass {
    public:
    bool operator== (const MyClass& that) {
        return compare_for_equality_somehow(that);
        }
    bool operator< (const MyClass& that) {
        return compare_for_lessality_somehow(that);
        }
    ....
    using namespace std::rel_ops; // operators >, >=, <=, ! are "magically" defined!
    };

(我刚刚为类比目的发明了“不道德”这个词,我的头因某种原因拒绝提出正确的数学术语......)

我创建了一个简单的标头<step_ops.hpp>,其内容有点模仿Utility标头中的std::rel_ops命名空间。我在几次编译后可以看到,它只是工作(TM)。我可以/我应该使用这个技巧吗?如果我创建一个类并使用using namespace MyLibrary::increment_operators(例如),我可能会遇到哪些陷阱?

也许更重要,更重要的是:我是否刚刚重新开发了轮子,或者我刚刚创建了一个可以聚合到这类项目的有用的小型库?几乎所有我尝试用C ++做的实验让我自己恢复速度和协作的东西似乎已经被boost::do_something工具覆盖了,这让我有点伤心,因为我花了这么多钱时间过去了。

4 个答案:

答案 0 :(得分:4)

Boost在Boost Operators实用程序库中提供此功能。它的实现有点不同,但实现了相同的结果。

  

我可以/我应该使用这个技巧吗?

尽可能使用它;删除冗余和重复的代码是重构的基本原则,是一个很好的实践。

  

我是否刚刚再次重新启动了这个轮子,或者我刚刚创建了一个可以聚合到这类项目的有用的小型库?

我想你可以说你已经重新发明了轮子。我认为这不一定是坏事:我发现如果我自己实施某些东西,我通常会更好地理解它并在整个过程中学到很多东西。

答案 1 :(得分:1)

如果你有空闲时间,并需要经验,重新发明你喜欢的所有轮子。我自己做了几个,以提高我对基本概念的了解。它可以帮助很多。

答案 2 :(得分:0)

或者您可以使用<template T>它内置于c ++语言中,它允许您为同一代码使用多个类型,您需要做的就是确保每个使用新类的类使用类template定义的运算符定义了所有方法。

有关template http://www.cplusplus.com/doc/tutorial/templates/

的详情,请参阅文档

答案 3 :(得分:0)

我是原始海报,只是回答说我最终注册了StackOverflow。因此,我有一个新手柄。现在说谢谢答案,特别是HeadGeek的动机问题。另外,为了纠正自己并对tjm的评论进行说明,使用代码的确切形式并不像我发布的那样。使用此方法的更正确方法是通过using将每个运算符引入类的自己的范围:

namespace scope {
class MyClass {
  public:
  bool operator== (const MyClass& that) {
    return compare_for_equality_somehow(that);
    }
  bool operator< (const MyClass& that) {
    return compare_for_lessality_somehow(that);
    }
  ....
  // using namespace std::rel_ops; // that one is incorrect
  };
using std::rel_ops::operator=!; // similarly for >, >=, <=
} // end of namespace

如果在原始帖子中完成,标题编译正常,但当标题包含在同时包含并使用rel_ops的项目中时,会出现编译错误。更重要的是,该方法将为类的范围中定义的所有类带来所有运算符 - 绝对不可取。使用这种明确using的方法,只需要将所需的运算符纳入范围,并根据需要对它们进行解析。

谢谢大家,很快见到你。

另外,请不要提出这个问题,除非你真的觉得它有什么可以提供的东西 - 自从Boost已经拥有它以来它并不是什么新东西 - 我发布了这个用于双重信息的目的