为什么标准只要求 std::distance 的输入迭代器,而不是前向迭代器?

问题描述 投票:0回答:1

我很困惑地发现std::distance的模板参数要求

是一个
LegacyInputIterator而不是LegacyForwardIterator

由于仅输入迭代器没有多遍保证,因此它们之间的“距离”概念没有可靠或有用的意义。

所以下面的代码是有意义的(即使效率有点低):

#include<iostream> #include <list> int main() { std::list <int> l{1, 2, 3, 4, 5}; std::cout << std::distance(l.begin(), l.end()) << '\n'; return 0; }
但是下面的代码却没有:

#include<iostream> int main() { auto z = std::istreambuf_iterator<char>(std::cin.rdbuf()); auto e = std::istreambuf_iterator<char>(); std::cout << std::distance(z, e) << '\n'; }

std::distance

可能已经计算了输入的字符,但根据
istreambuf_iterator
的定义,这些字符已经消失,永远不会返回。

这应该是格式不正确或至少是未定义的行为,但事实并非如此。

(而不是 std::cin,我可能会打开一个到命名管道的文件流,这只会让我“啜饮”出数据的消防水带。)

是否有任何委员会成员讨论或提案语言将

std::distance

 放入标准中来解释要求的选择?

c++ language-lawyer language-design
1个回答
0
投票
您不应将参数类型视为对输入的要求。它们更多的是关于功能本身需要什么。换句话说,如果您看到这样的签名:

void func(const std::string& x);
您不认为该函数需要常量字符串。您认为无论该函数做什么,它都只需要对其参数应用读取操作。

这里也一样。

LegacyInputIterator

LegacyForwardIterator
 之间的区别在于后者支持多通道算法。但你不需要它来计算距离。这是单遍算法。

如果您将

LegacyForwardIterator

 作为 
std::distance
 的输入参数,您将不允许 
LegacyInputIterators
 作为输入。事实上,支持此类功能并没有多大意义,但它是免费的。谁知道呢,也许某个地方有这样的用例

© www.soinside.com 2019 - 2024. All rights reserved.