3月21日 st 标准委员会投票赞成批准std::iterator
中提议的P0174的弃用:
对于读者而言,很长的void参数序列不仅仅是简单地在类定义本身中提供预期的
typedef
s,这是当前工作草案采用的方法,遵循{中设置的模式{3}}
鼓励从std::iterator
继承c++14之前从迭代器样板实现中删除乏味。但弃用将需要以下其中一项:
typedef
s auto
而不是依赖于迭代器来声明类型std::iterator
有人可以告诉我我应该期待哪些选项,因为我设计的自定义迭代器着眼于std::iterator_traits
兼容性?
答案 0 :(得分:31)
讨论的替代方案很明确,但我觉得需要一个代码示例。
鉴于没有语言替代品且不依赖于boost或您自己的迭代器基类版本,以下使用std::iterator
的代码将被修复为下面的代码。
std::iterator
template<long FROM, long TO>
class Range {
public:
// member typedefs provided through inheriting from std::iterator
class iterator: public std::iterator<
std::forward_iterator_tag, // iterator_category
long, // value_type
long, // difference_type
const long*, // pointer
const long& // reference
>{
long num = FROM;
public:
iterator(long _num = 0) : num(_num) {}
iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;}
iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
bool operator==(iterator other) const {return num == other.num;}
bool operator!=(iterator other) const {return !(*this == other);}
long operator*() {return num;}
};
iterator begin() {return FROM;}
iterator end() {return TO >= FROM? TO+1 : TO-1;}
};
(来自http://en.cppreference.com/w/cpp/iterator/iterator的代码,原始作者的许可)。
std::iterator
template<long FROM, long TO>
class Range {
public:
class iterator {
long num = FROM;
public:
iterator(long _num = 0) : num(_num) {}
iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;}
iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
bool operator==(iterator other) const {return num == other.num;}
bool operator!=(iterator other) const {return !(*this == other);}
long operator*() {return num;}
// iterator traits
using difference_type = long;
using value_type = long;
using pointer = const long*;
using reference = const long&;
using iterator_category = std::forward_iterator_tag;
};
iterator begin() {return FROM;}
iterator end() {return TO >= FROM? TO+1 : TO-1;}
};
答案 1 :(得分:30)
选项3是选项1的严格打字版本,因为您必须编写所有相同的typedefs
,但另外包装iterator_traits<X>
。
选项2作为解决方案是不可行的。您可以推断出某些类型(例如reference
只是decltype(*it)
),但您无法推断iterator_category
。您无法仅通过操作来区分input_iterator_tag
和forward_iterator_tag
,因为您无法反复检查迭代器是否满足多通道保证。另外,如果迭代器产生可变引用,则无法真正区分它们和output_iterator_tag
。必须在某处明确提供它们。
留下选项1.猜猜我们应该习惯于编写所有样板文件。我是一个人,欢迎我们新的腕管道领主。