[英]Are the “defaults” for the type alises in std::iterator_traits always correct?
I've read on cppreference that with C++20, it's possible to omit specifying the type aliases reference
, pointer
and iterator_category
when defining a new iterator.我在cppreference上读过,使用 C++20,在定义新迭代器时可以省略指定类型别名
reference
、 pointer
和iterator_category
。 In this case, the corresponding aliases in std::iterator_traits
will have "default" values.在这种情况下,
std::iterator_traits
中的相应别名将具有“默认”值。 The details of this are a bit confusing to me, so I'm trying to split this topic into answerable questions.这个细节让我有点困惑,所以我试图把这个话题分解成可以回答的问题。 So, my first question is: Are all (or some) of these "default" aliases guaranteed to be correct?
所以,我的第一个问题是:这些“默认”别名中的所有(或部分)是否都保证是正确的?
As I understand it, the iterator_category
tags are based on the C++17 named requirements.据我了解,
iterator_category
标签基于 C++17 命名要求。 If an iterator satisfies the forward iterator requirement (but not the bidirectional requirement), its tag should be forward_iterator_tag
.如果迭代器满足前向迭代器要求(但不满足双向要求),则其标记应为
forward_iterator_tag
。
I'm specifically worried about the distinction between forward_iterator_tag
and input_iterator_tag
.我特别担心
forward_iterator_tag
和input_iterator_tag
之间的区别。 Forward iterators have to be able to be used in multipass algorithms, but I don't think the compiler checks that this is the case.前向迭代器必须能够在多通道算法中使用,但我认为编译器不会检查这种情况。 Are there cases where I can know that the "default" aliases will be correct (eg an output iterator is always classified correctly, or the default
reference
alias is always correct)?在某些情况下我可以知道“默认”别名是正确的(例如,output 迭代器总是被正确分类,或者默认
reference
别名总是正确的)?
Define "correct".定义“正确”。 The point of having defaults is to cover the most common cases adequately, while still allowing them to be overridden manually when needed.
使用默认值的目的是充分覆盖最常见的情况,同时仍允许在需要时手动覆盖它们。 This implies that, in those cases, the defaults wouldn't be appropriate.
这意味着,在这些情况下,默认值是不合适的。
Can you write a type where the defaults are not valid?你能写一个默认值无效的类型吗?
reference
is by default whatever *t
returns, so it's pretty hard for the default to be wrong even for proxy iterators.默认情况下,
reference
是*t
返回的任何内容,因此即使对于代理迭代器,默认值也很难出错。
pointer
is defined to be what operator->
would yield, but if no such thing exists, it would be void
. pointer
被定义为operator->
将产生的东西,但如果不存在这样的东西,它将是void
。 But that's OK, because the pointer
trait isn't really useful since operator->
isn't even required to be supported by any iterator type.但这没关系,因为
pointer
trait 并不是真正有用,因为operator->
甚至不需要被任何迭代器类型支持。
iterator_category
's default is more likely to yield an improper result, but it's not exactly common. iterator_category
的默认值更有可能产生不正确的结果,但这并不常见。 Input iterators are less common than other types, so you can easily avoid issues by just specifying the tag when you're writing an input iterator.输入迭代器不像其他类型那样常见,因此您可以通过在编写输入迭代器时指定标签来轻松避免问题。
It should also be noted that iterator_category
specifies conformance to C++17 iterator categories.还应注意,
iterator_category
指定符合 C++17 迭代器类别。 The C++20 concepts can be overridden by providing an iterator_concept
tag specification.通过提供
iterator_concept
标记规范,可以覆盖 C++20 概念。
Note also that the ITER_CONCEPT
meta-function in C++20 that extracts the iterator tag for the C++20 concepts explicitly bypasses the defaulting mechanism of iterator_category
.另请注意,C++20 中为 C++20 概念提取迭代器标记的
ITER_CONCEPT
元函数显式绕过了iterator_category
的默认机制。 That is, it only checks the tag you explicitly specify on the iterator itself (either via iterator_concept
or iterator_category
as a fallback) or on an iterator_traits
specialization , not the default that the primary iterator_traits
template would produce.也就是说,它只检查您在迭代器本身(通过
iterator_concept
或iterator_category
作为后备)或iterator_traits
特化上明确指定的标签,而不是主iterator_traits
模板将产生的默认值。 So C++20's concepts requires you to specify the tag in some way, despite iterator_traits::iterator_category
having a defaulting mechanism.因此,尽管
iterator_traits::iterator_category
具有默认机制,但 C++20 的概念要求您以某种方式指定标记。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.