【发布时间】:2017-08-08 16:23:09
【问题描述】:
C++17 引入了 ContiguousIterator http://en.cppreference.com/w/cpp/iterator 的概念。
但是,std::iterator_traits<It>::iterator_category 似乎没有计划报告 contiguous_iterator_tag(与我们现在拥有 random_access_iterator_tag 的方式相同)。
为什么contiguous_iterator_tag 不见了?
是否有确定迭代器是否连续的常规协议? 还是编译时测试?
过去我提到对于容器如果有一个.data() 成员可以转换为指向::value 类型的指针并且有.size() 成员可以转换为指针差异,那么一个应该假设容器是连续的,但我无法提取迭代器的类似功能。
一种解决方案可能是同时为连续迭代器提供data 函数。
当然,如果&(it[n]) == (&(*it)) + n 对所有n 都有效,则连续概念有效,但这不能在编译时检查。
编辑:我发现这个视频将其置于更广泛的 C++ 概念背景中。 CppCon 2016: "Building and Extending the Iterator Hierarchy in a Modern, Multicore World" 由 Patrick Niedzielski 撰写。该解决方案使用概念(Lite),但最终的想法是连续迭代器应该实现 pointer_from 函数(与我的 data(...) 函数相同)。
结论是,概念将有助于将理论形式化,但它们并不神奇,因为某人、某处将在连续的迭代器上定义新的特别命名的函数。
该演讲概括了分段迭代器(具有相应的函数segment 和local),不幸的是它没有提及跨步指针。
2020 年编辑:
标准现在有
struct contiguous_iterator_tag: public random_access_iterator_tag { };
【问题讨论】:
-
为什么
contiguous_iterator_tag不见了? ← 因为它会默默地破坏 C++17 之前的代码,假设std::vector::iterator恰好是一个随机访问迭代器? -
@kennytm,微妙的原因。但是,如果正确使用特征(我认为),可以使其向后兼容(例如,如果
random_access_iterator派生自contiguous_iterator_tag)。如果仅仅因为 trait 使用不当而中断,那将是不幸的。 -
情况似乎不太乐观。我认为一个可能的想法是为所有连续迭代器提供
.data()成员或data(ContiguousIterator it)函数,这类似于当前具有.data()成员的容器是连续的. -
好吧,他们对临时多态性有什么期望? C++ 背后的一个动机是避免它。整个 iterator_tag 应该被驱逐为掠夺。
-
@JiveDadson 我部分同意,原因如下。我得出的结论是,对于应该由操作员检测实施的东西,标签是一个不好的替代品。比如有operator++就是前向迭代器,有operator+=就是随机访问,有数据函数就是连续迭代器,等等。
标签: c++ iterator c++17 c++20 iterator-traits