std :: iterator_traits libstdc 和libc 之间的分歧



给定:

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_­typevalue_­typepointerreferenceiterator_­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_­tagoutput_­iterator_­tagforward_­iterator_­tagbidirectional_­iterator_­tagrandom_­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>中任何成员别名的方法可能更好。

相关内容

  • 没有找到相关文章

最新更新