No,没有编译时特征。
The C++1z 标准草案 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf将连续性定义为运行时属性迭代器范围的。注意没有编译时间std::contiguous_iterator_tag
对应于这个迭代器类别。
24.2 迭代器要求 [iterator.requirements]
24.2.1 一般情况 [iterator.requirements.general]
5 个迭代器,进一步满足以下要求:对于积分
价值观n
和可解引用的迭代器值a
and (a + n), *(a + n)
相当于*(addressof(*a) + n)
, 称为连续的
迭代器。 [ 注意:例如,“指向 int 的指针”类型是一个
连续迭代器,但是reverse_iterator<int *>
不是。对于有效的
迭代器范围[a,b)
具有可解引用的a
,对应的范围
由指针表示的是[addressof(*a),addressof(*a) + (b - a));
b
可能不可取消引用。 ——尾注]
在运行时测试这一点的一种方法是
#include <array>
#include <deque>
#include <list>
#include <iostream>
#include <iterator>
#include <map>
#include <memory>
#include <string>
#include <unordered_set>
#include <vector>
template<class I>
auto is_contiguous(I first, I last)
{
auto test = true;
auto const n = std::distance(first, last);
for (auto i = 0; i < n && test; ++i) {
test &= *(std::next(first, i)) == *(std::next(std::addressof(*first), i));
}
return test;
}
int main()
{
auto l = std::list<int> { 1, 2, 3 };
auto m = std::map<int, int> { {1, 1}, {2,2}, {3,3} };
auto u = std::unordered_multiset<int> { 1, 1, 1 };
auto d = std::deque<int>(4000);
int c[] = { 1, 2, 3 };
auto a = std::array<int, 3> {{ 1, 2, 3 }};
auto s = std::string {"Hello world!"};
auto v = std::vector<int> { 1, 2, 3, };
std::cout << std::boolalpha << is_contiguous(l.begin(), l.end()) << "\n";
std::cout << std::boolalpha << is_contiguous(m.begin(), m.end()) << "\n";
std::cout << std::boolalpha << is_contiguous(u.begin(), u.end()) << "\n";
std::cout << std::boolalpha << is_contiguous(d.begin(), d.end()) << "\n";
std::cout << std::boolalpha << is_contiguous(d.begin(), d.begin() + 1000) << "\n";
std::cout << std::boolalpha << is_contiguous(std::begin(c), std::end(c)) << "\n";
std::cout << std::boolalpha << is_contiguous(a.begin(), a.end()) << "\n";
std::cout << std::boolalpha << is_contiguous(s.begin(), s.end()) << "\n";
std::cout << std::boolalpha << is_contiguous(v.begin(), v.end()) << "\n";
std::cout << std::boolalpha << is_contiguous(v.rbegin(), v.rend()) << "\n";
}
实例 http://coliru.stacked-crooked.com/a/e0e37d9aa7f8c305。这打印false
为了list
, map
and unordered_multimap
, and true
对于 C 数组,以及std::array
, string
and vector
。它打印true
对于a内的小子范围deque
and false
对于大的子范围。它还打印false
对于由反向迭代器组成的迭代器范围。
UPDATE:正如@T.C. 评论的那样。原本的N3884 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3884.pdf提案确实有一个
struct contiguous_iterator_tag : random_access_iterator_tag {};
这样迭代器类别上的标签调度就不会中断。但是,这会破坏具有类模板专门化的非惯用代码random_access_iterator_tag
。因此,当前草案不包含新的迭代器类别标签。