可以/我应该从STL迭代器继承? [英] Can/Should i inherit from STL iterator?

查看:116
本文介绍了可以/我应该从STL迭代器继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以/我应该继承STL迭代器来实现我自己的迭代器类吗?

Can/Should i inherit from STL iterator to implement my own iterator class? If no, why not?

推荐答案

短回答



与常规类型别名相比, std :: iterator 类不提供太多,甚至通过不明确提供名称和依赖模板的顺序来模糊它们参数。它将在C ++ 17中被弃用,并且很可能在几年后消失。

Short answer

Many consider that the class std::iterator does not offer much compared to regular type aliases, and even obfuscates them a bit by not explicitly providing the names and relying on the order of the template parameters instead. It will be deprecated in C++17 and is likely to be gone in a few years.

这意味着你不应该使用 std :: iterator 。如果您对完整的故事感兴趣,您可以阅读下面的整篇文章(由于它已在弃用提案之前开始,因此有一些冗余)。

This means that you shouldn't use std::iterator anymore. You can read the whole post below if you're interested in the full story (there's a bit of redundancy since it has been started before the deprecation proposal).

如果您对历史记录不感兴趣,可以忽略以下内容。以下片段甚至与自身矛盾多次。

You can ignore everything below if you're not interested in history. The following fragments even contradict themselves several times.

今天(C ++ 11 / C ++ 14),标准似乎意味着不再是继承自 std :: iterator 以实现自定义迭代器的好主意。以下简短说明,请参阅 N3931

As of today (C++11/C++14), the standard seems to imply that it isn't a good idea anymore to inherit from std::iterator to implement custom iterators. Here is a brief explanation, from N3931:


虽然标准版已经犯了这么多错误,但我建议不要描述 directory_iterator recursive_directory_iterator 作为派生自 std :: iterator ,因为这是对实现的绑定要求。相反,它们应该被描述为具有适当的typedef,并将其留给实现者来决定如何提供它们。 ( is_base_of 的用户可以看到差异,而不是他们应该问这个问题。)

Although the Standard has made this mistake almost a dozen times, I recommend not depicting directory_iterator and recursive_directory_iterator as deriving from std::iterator, since that's a binding requirement on implementations. Instead they should be depicted as having the appropriate typedefs, and leave it up to implementers to decide how to provide them. (The difference is observable to users with is_base_of, not that they should be asking that question.)

[2014-02-08 Daniel评论并提供文字]

[2014-02-08 Daniel comments and provides wording]

这个问题基本上类似于用来移除要求的解决方案如 unary_function 和朋友派生/n3198.htmrel =nofollow> N3198 ,我强烈赞成在这里遵循的精神。我想补充一点,基本上所有的更新的迭代器类型(如 regex 相关的迭代器)不是从 std :: iterator

This issue is basically similar to the kind of solution that had been used to remove the requirement to derive from unary_function and friends as described by N3198 and I'm strongly in favour to follow that spirit here as well. I'd like to add that basically all "newer" iterator types (such as the regex related iterator) don't derive from std::iterator either.

本文引用 N3198 ,它本身声明它遵循 N3145 。仅存在提供 typedef 的类的原因如下:

The paper cites N3198 which itself states that it follows the deprecation discussed in N3145. The reasons for deprecating the classes that only exist to provide typedefs are given as such:


我们的概念经验使我们有信心,如果类型和函数的可用性足够,很少需要依赖于特定的基类派生类关系。新的语言工具允许我们甚至在没有语言支持的概念的情况下推断类类型中的类型名称的存在,这将在它们之间引入一个更弱的耦合。用关联类型替换继承的另一个优点是,这将减少出现歧义的情况的数量:如果类型将从 unary_function binary_function (这是有道理的,如果一个函子是一元函数和二元函数对象)。

Our experience with concepts gives us confidence that it is rarely necessary to depend on specific base class-derived class relations, if availability of types and functions is sufficient. The new language tools allow us even in the absence of language-supported concepts to deduce the existence of typenames in class types, which would introduce a much weaker coupling among them. Another advantage of replacing inheritance by associated types is the fact, that this will reduce the number of cases, where ambiguities arise: This can easily happen, if a type would inherit both from unary_function and binary_function (This makes sense, if a functor is both an unary and a binary function object).

tl; dr :仅提供 typedef 的类现在被视为无用。此外,当不需要时,它们增加耦合,更冗长,并且在某些角落情况下可能具有不期望的副作用。(参见前面的引文)。

tl;dr: classes which only provide typedefs are now deemed useless. Moreover, they increase coupling when it is not needed, are more verbose, and can have unwanted side effects in some corner cases (see the previous quotation).

更新从N4245发出问题2438似乎实际上与我之前声称的矛盾:

Update: issue 2438 from N4245 seems to actually contradict what I asserted earlier:


,九个STL迭代器被描述为从 std :: iterator 得到它们的 iterator_category / etc。 typedefs。不幸的是(和无意的),这也要求继承,这是可观察的(不只是通过 is_base_of ,但也重载分辨率)。这是不幸的,因为它混淆了用户,他们可能被误导成认为自己的迭代器必须从 std :: iterator 派生,或重载函数以 std :: iterator 有点意义。这也是无意的,因为STL的最重要的迭代器,容器迭代器,不需要从 std :: iterator 派生。 (有些甚至被允许为原始指针。)最后,这不必要地约束了实现者,他们可能不想从 std :: iterator 派生。 (例如,为了简化调试器视图。)

For LWG convenience, nine STL iterators are depicted as deriving from std::iterator to get their iterator_category/etc. typedefs. Unfortunately (and unintentionally), this also mandates the inheritance, which is observable (not just through is_base_of, but also overload resolution). This is unfortunate because it confuses users, who can be misled into thinking that their own iterators must derive from std::iterator, or that overloading functions to take std::iterator is somehow meaningful. This is also unintentional because the STL's most important iterators, the container iterators, aren't required to derive from std::iterator. (Some are even allowed to be raw pointers.) Finally, this unnecessarily constrains implementers, who may not want to derive from std::iterator. (For example, to simplify debugger views.)

总之,我错了,@aschepler是对的:可以使用,但它确定不是必需的 - 它也不鼓励。整个let's remove std :: iterator 存在的标准不限制标准库实现者。

To sum up, I was wrong, @aschepler was right: it can be used, but it is certainely not required - it isn't discouraged either. The whole "let's remove std::iterator" thing exists for the standard not to constrain the standard library implementers.

第3轮 P0174R0 建议不再使用 std :: iterator 以便将来可能删除。该建议已经很好地解释了为什么它应该被弃用,所以这里我们去:

Round 3: P0174R0 proposes to deprecate std::iterator for a possible removal in the future. The proposal is already pretty good at explaining why it should be deprecated, so here we go:


void参数的长序列少得多向读者提供的不仅仅是在类定义本身中提供期望的typedef,这是当前工作草案所采用的方法,遵循C ++ 14中设置的模式,其中我们不赞成使用来自unary_function和binary_function的函数库。

The long sequence of void arguments is much less clear to the reader than simply providing the expected typedefs in the class definition itself, which is the approach taken by the current working draft, following the pattern set in C++14 where we deprecated the derivation throughout the library of functors from unary_function and binary_function.

除了降低清晰度之外,迭代器模板还为不经意的人打开了一个陷阱,因为在典型的用法中,它将是一个依赖的基类,不是在类或其成员函数内查找名称。这导致惊讶的用户试图理解为什么以下简单用法不工作:

In addition to the reduced clarity, the iterator template also lays a trap for the unwary, as in typical usage it will be a dependent base class, which means it will not be looking into during name lookup from within the class or its member functions. This leads to surprised users trying to understand why the following simple usage does not work:

#include <iterator>

template <typename T>
struct MyIterator : std::iterator<std::random_access_iterator_tag, T> {
   value_type data;  // Error: value_type is not found by name lookup 

   // ... implementations details elided ...
};

清楚的理由足以说服LWG将标准库规范更新为不再授权标准迭代器适配器从std :: iterator派生,所以在标准本身中没有进一步使用这个模板。

The reason of clarity alone was sufficient to persuade the LWG to update the standard library specification to no longer mandate the standard iterator adapators as deriving from std::iterator, so there is no further use of this template within the standard itself. Therefore, it looks like a strong candidate for deprecation.

这有点累了,不是每个人都同意,所以我会让你自己得出结论。如果委员会最终决定 std :: iterator 应该被弃用,那么它将清楚地表明你不应该使用它。请注意,后续文章突出显示了对移除 std :: iterator 的极大支持:

This is becoming a bit tiring and not everyone seems to agree, so I will let you draw your own conclusions. If the committee eventually decides that std::iterator should be deprecated, then it will make it pretty clear that you shouldn't use it anymore. Note that the follow-up paper highlights a great support for the removal of std::iterator:


Update from Jacksonville,2016:

Update from Jacksonville, 2016:

投票:取消迭代器对于C ++ 17?

SF F N A SA

6 10 1 0 0

Poll: Deprecate iterator for C++17??
SF  F   N   A   SA
6    10  1    0   0

在上述轮询结果中, > SA 代表强烈地 ,中性,

In the above poll results, SF, F, N, A and SA stand for Strongly For, For, Neutral, Against and Strongly Against.


2016年奥卢更新:

投票:仍然想要弃用 std :: iterator?

SF FNA SA

3 6 3 2 0

Poll: Still want to deprecate std::iterator?
SF F N A SA
3   6  3  2  0

这篇关于可以/我应该从STL迭代器继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆