3

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

我在一些 C++ 书籍和教程中看到,在定义您自己的具有可迭代值(可递增)语义的类时,您可以operator++为它重载(我将在这里陈述的所有内容我猜也适用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!
    };

(我只是出于类比的目的发明了“lessality”这个词,我的脑袋由于某种原因拒绝提出正确的数学术语......)

I created a simple header <step_ops.hpp> whose content somewhat imitates the std::rel_ops namespace found in the Utility header. Fro what I can see after a couple of compiles, it just works(TM). Can I / Should I use this trick? What are possible pitfalls I could come up against if I create a class and use a using namespace MyLibrary::increment_operators (for example)?

And maybe much, MUCH more important: Have I just reinvented the wheel again, or have I just created a useful small library that could be aggregated to such kinds of projects? Pretty much any experiments that I have tried to do with C++ to get myself back up-to-speed and collaborate stuff seem to already be covered under a boost::do_something facility and it makes me kind of sad that I have spent so much time away.

4

4 回答 4

4

Boost provides this functionality in the Boost Operators utility library. Its implementation is a little different, but achieves the same result.

Can I / Should I use this trick?

Use it wherever you can; cutting out redundant and repetitive code is a fundamental principle of refactoring and is a good practice to get into.

Have I just reinvented the wheel again, or have I just created a useful small library that could be aggregated to such kinds of projects?

I guess you could say then that you've reinvented the wheel. I don't think that's necessarily a bad thing, though: I find that if I implement something myself I usually understand it much better and learn a lot through the process.

于 2010-07-14T00:30:00.767 回答
1

If you've got the time to spare, and need the experience, reinvent all the wheels you like. I've done several myself, to improve my knowledge of the underlying concepts. It can help a lot.

于 2010-07-14T00:38:40.970 回答
0

Alternatively you could use <template T> it is built right into the c++ language, it allows you to use multiple types for the same code, all you need to do is make sure that for each class there that uses the newly defined operator with class template all methods are defined.

See the documentation for more info about template http://www.cplusplus.com/doc/tutorial/templates/

于 2010-07-14T00:36:32.990 回答
0

I'm the original poster, just answering to say that I finally registered to StackOverflow. As such I have a new handle. Now saying thanks to the answers, in particular HeadGeek with the motivation issue. Also, to correct myself and folloiwing on tjm's comment, the exact form the code is used is not as I posted. The more correct way of using this method is to bring each operator into the class's own scope via 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

If done as in my original post, the header compiles fine, but compilation errors are brought when the header is included in a project that also includes and uses rel_ops somewhere. More importantly, that method would bring all operators for all classes defined in the class's scope -- definitively not desirable. With this approach of explicitly using, only the needed operators are brought into scope, and they are resolved as needed.

Thanks everyone, seeing you soon.

(Also, please, don't upvote this question unless you really feel it has something to offer -- it is nothing new since Boost already has it -- I posted this for dual informative purposes)

于 2010-08-10T22:04:14.130 回答