我刚刚编写了一些代码来测试std :: equal的行为,并且感到惊讶:
int main()
{
try
{
std::list<int> lst1;
std::list<int> lst2;
if(!std::equal(lst1.begin(), lst1.end(), lst2.begin()))
throw std::logic_error("Error: 2 empty lists should always be equal");
lst2.push_back(5);
if(std::equal(lst1.begin(), lst1.end(), lst2.begin()))
throw std::logic_error("Error: comparing 2 lists where one is not empty should not be equal");
}
catch(std::exception& e)
{
std::cerr << e.what();
}
}
输出(对我来说很惊讶):
Error: comparing 2 lists where one is not empty should not be equal
观察:为什么std::equal首先检查2个容器是否具有相同的size()
?有合理的理由吗?
答案 0 :(得分:12)
观察:为什么std :: equal首先检查2个容器是否具有相同的大小()?有合理的理由吗?
如何?您没有将容器传递给函数,而是传入迭代器。函数无法知道第二个容器的大小。它所能做的只是假设用户传递了两个有效的容器范围(即第二个范围被正确指定为半开区间[lst2.begin()
,lst2.begin()
- lst1.begin()
+ lst1.end()
[)并采取相应行动。
答案 1 :(得分:4)
您可以随时编写自己的版本,以实现您想要的效果:
template <class InputIterator1, class InputIterator2>
bool equalx(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2)
{
while ((first1 != last1) && (first2 != last2))
{
if (*first1 != *first2) // or: if (!pred(*first1,*first2)), for pred version
return false;
++first1; ++first2;
}
return (first1 == last1) && (first2 == last2);
}
为了确保两个范围具有相同数量的元素,签名必须包含第二个范围的结尾。
答案 2 :(得分:3)
因为检查大小可能是O(n)
操作。
答案 3 :(得分:2)
它给你正确答案 - 你告诉它检查两个容器在lst1.begin()
到lst1.end()
范围内是否相等。就equal()
而言,您仍在比较两个空列表。如果您将代码更改为从lst2.begin()
到lst2.end()
进行比较,那么您将得到预期的结果。
答案 4 :(得分:0)
C ++ 14增加了一个四参数重载,就像R Samuel Klatchko的答案中的重载一样。至少我检查的两个STL实现(libc ++和MSVC)为随机访问迭代器实现了明显的距离检查前端优化。