我很困惑地发现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
放入标准中来解释要求的选择?
void func(const std::string& x);
您不认为该函数需要常量字符串。您认为无论该函数做什么,它都只需要对其参数应用读取操作。这里也一样。
LegacyInputIterator
和
LegacyForwardIterator
之间的区别在于后者支持多通道算法。但你不需要它来计算距离。这是单遍算法。如果您将
LegacyForwardIterator
作为
std::distance
的输入参数,您将不允许
LegacyInputIterators
作为输入。事实上,支持此类功能并没有多大意义,但它是免费的。谁知道呢,也许某个地方有这样的用例