我有一个问题可能已经回答了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
工具覆盖了,这让我有点伤心,因为我花了这么多钱时间过去了。
答案 0 :(得分:4)
Boost在Boost Operators实用程序库中提供此功能。它的实现有点不同,但实现了相同的结果。
我可以/我应该使用这个技巧吗?
尽可能使用它;删除冗余和重复的代码是重构的基本原则,是一个很好的实践。
我是否刚刚再次重新启动了这个轮子,或者我刚刚创建了一个可以聚合到这类项目的有用的小型库?
我想你可以说你已经重新发明了轮子。我认为这不一定是坏事:我发现如果我自己实施某些东西,我通常会更好地理解它并在整个过程中学到很多东西。
答案 1 :(得分:1)
如果你有空闲时间,并需要经验,重新发明你喜欢的所有轮子。我自己做了几个,以提高我对基本概念的了解。它可以帮助很多。
答案 2 :(得分:0)
或者您可以使用<template T>
它内置于c ++语言中,它允许您为同一代码使用多个类型,您需要做的就是确保每个使用新类的类使用类template
定义的运算符定义了所有方法。
答案 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已经拥有它以来它并不是什么新东西 - 我发布了这个用于双重信息的目的 )