给定:
struct Iter {
using value_type = int;
using difference_type = int;
using reference = int;
using pointer = int;
using iterator_category = int;
};
以下功能与libstc 息息相关,但无法针对libc 5.0.0:
进行编译。#include <iterator>
#include <type_traits>
static_assert(
std::is_same<
std::iterator_traits<Iter>::iterator_category,
Iter::iterator_category
>::value, "");
有错误:
错误:没有成员名为'
iterator_category
'in'std::__1::iterator_traits<Iter>
'std::is_same<std::iterator_traits<Iter>::iterator_category, Iter::iterator_category>::value, "");
如果Iter::iterator_category
是标准输入类别之一,例如,静态断言会成功。std::input_iterator_tag
。
IMHO不应该失败,因为[iterator.traits]#2中的C 草稿状态:
如果迭代器具有有效([temp.deduct])成员类型
difference_type
,value_type
,pointer
,reference
和iterator_category
,则iterator_traits<Iterator>
应有以下内容作为公开访问的成员:using difference_type = typename Iterator::difference_type; using value_type = typename Iterator::value_type; using pointer = typename Iterator::pointer; using reference = typename Iterator::reference; using iterator_category = typename Iterator::iterator_category;
否则,
iterator_traits<Iterator>
不得有上述任何名称的成员。
任何人都可以解释这是实现错误,还是为什么我的期望错了?
我们也有[std.iterator.tags]:
通常需要函数模板专业化来找出其迭代器参数最特定的类别是什么,以便该函数可以在编译时选择最有效的算法。为了促进这一点,库引入类别标签类,这些类别用作算法选择的编译时标签。它们是:
input_iterator_tag
,output_iterator_tag
,forward_iterator_tag
,bidirectional_iterator_tag
和random_acces_iterator_tag
。对于Iterator
类型的每个迭代器,iterator_traits<Iterator>::iterator_category
应定义为描述迭代器行为的最特定类别标签。namespace std { struct input_iterator_tag { }; struct output_iterator_tag { }; struct forward_iterator_tag: public input_iterator_tag { }; struct bidirectional_iterator_tag: public forward_iterator_tag { }; struct random_access_iterator_tag: public bidirectional_iterator_tag { }; }
int
不是其中一个标签之一,因此iterator_traits<Iter>::iterator_category
无法将您归还int
。我建议拥有无效的迭代器类别只是违反了iterator_traits
的先决条件 - 这并不一定意味着库必须失败,但这也不意味着失败是库错误。
但是,这些前提条件在[迭代器]中没有像在图书馆部分的其他部分那样明确地阐明。因此,我倾向于建议两个库都是正确的,但是LIBC 的方法不定义iterator_traits<Iter>
中任何成员别名的方法可能更好。