根据 cpp 首选项,std::move_iterator
将其::iterator_category
设置为其底层迭代器1的类别。
但我认为它充其量只能是一个输入/输出迭代器,因为对于前向迭代器reference
必须是左值引用,而move_iterator
reference
(以及返回类型operator*
)设置为右值引用2。
这是对迭代器具有错误类别的公然错误标记吗?
能够为我自己的迭代器执行此操作无疑是方便的。如果即使是标准库也这样做,我有什么理由不应该这样做吗?
1但是任何比random_access_iterator_tag
强的东西都会被截断为random_access_iterator_tag
,这很奇怪,因为contiguous_iterator_tag
应该只用于::iterator_concept
。
2或者,如果它不是引用,则保持原样,但底层迭代器也不应该将自己宣传为前向迭代器。
一方面,关于前向迭代器需求的 cpp偏好文章是错误的(已经被某人修复了)。reference
必须是任何引用(&
或&&
),而不是特定的左值引用(&
)。意思是move_iterator
确实符合。
但另一方面,自动确定::iterator_category
使用不同的措辞,这只允许左值引用:
concept cpp17-forward-iterator = ... && is_lvalue_reference_v<iter_reference_t<I>>
这看起来像一个标准缺陷。我已经写信给lwgchair@gmail.com
,等待回复。
前向迭代器能够使用任何类型的引用的来源:
[forward.iterators]/1.3
:
如果
。X
是一个可变迭代器,reference
是对T
的引用;如果X
是一个常量迭代器,reference
是对const T
的引用
另见LWG1211(从2009年开始),它提出了同样的问题,并由N3066(2010年)解决,它将措辞从"左值参考"更改为"任何参考"。(感谢@康桓瑋的链接)。