为什么 std::iterator 被弃用?
Why is std::iterator deprecated?
Template class std::iterator
is set to be deprecated in C++17. Why so? It has been a handy way to make sure std::iterator_traits
有效,特别是如果您可以使用默认模板参数。在 C++17 中还有其他方法吗?
来自the proposal that suggested its deprecation:
As an aid to writing iterator classes, the original standard library supplied the iterator class template to automate the declaration of the five typedefs expected of every iterator by iterator_traits. This was then used in the library itself, for instance in the specification of std::ostream_iterator
:
template <class T, class charT = char, class traits = char_traits<charT> >
class ostream_iterator:
public iterator<output_iterator_tag, void, void, void, void>;
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 ...
};
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.
STL的推理也可以在LWG 2438. (h/t )
中看到
至于其他一些方法,不是真的。您基本上可以实现自己的 std::iterator
版本(不太难)或手动写出所有这些 typedef(也不太难,为了清晰起见,我实际上更喜欢它)。
正如 Barry 所述,工作组已决定在 class 中显式声明类型比从 std::iterator
.
继承更具可读性并且导致的意外更少
不过,转换为显式类型并不难(下面的示例取自 www.fluentcpp.com here)。给定一个像这样声明的 class:
class MyIterator
: public std::iterator<std::forward_iterator_tag, int, int, int*, int&>
{
...
没有std::iterator
的class变成:
class MyIterator
{
public:
using iterator_category = std::forward_iterator_tag;
using value_type = int;
using difference_type = int;
using pointer = int*;
using reference = int&;
// ...
Template class std::iterator
is set to be deprecated in C++17. Why so? It has been a handy way to make sure std::iterator_traits
有效,特别是如果您可以使用默认模板参数。在 C++17 中还有其他方法吗?
来自the proposal that suggested its deprecation:
As an aid to writing iterator classes, the original standard library supplied the iterator class template to automate the declaration of the five typedefs expected of every iterator by iterator_traits. This was then used in the library itself, for instance in the specification of
std::ostream_iterator
:template <class T, class charT = char, class traits = char_traits<charT> > class ostream_iterator: public iterator<output_iterator_tag, void, void, void, void>;
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 fromunary_function
andbinary_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 ... };
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.
STL的推理也可以在LWG 2438. (h/t
至于其他一些方法,不是真的。您基本上可以实现自己的 std::iterator
版本(不太难)或手动写出所有这些 typedef(也不太难,为了清晰起见,我实际上更喜欢它)。
正如 Barry 所述,工作组已决定在 class 中显式声明类型比从 std::iterator
.
不过,转换为显式类型并不难(下面的示例取自 www.fluentcpp.com here)。给定一个像这样声明的 class:
class MyIterator
: public std::iterator<std::forward_iterator_tag, int, int, int*, int&>
{
...
没有std::iterator
的class变成:
class MyIterator
{
public:
using iterator_category = std::forward_iterator_tag;
using value_type = int;
using difference_type = int;
using pointer = int*;
using reference = int&;
// ...