【发布时间】:2018-11-04 01:49:26
【问题描述】:
来自the standard,std::includes:
如果
[first2, last2)为空或者[first2, last2)范围内的每个元素都包含在[first1, last1)范围内,则返回:true。 否则返回false。
注意:因为这是在 [alg.set.operations] 下,范围必须排序
从字面上看,如果我们让R1=[first1, last1) 和R2=[first2, last2),这是评估:
∀a∈R2 a∈R1
但是,这并不是实际评估的内容。对于R1={1} 和R2={1,1,1},std::includes(R1, R2) 返回 false:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>
int main() {
std::vector<int> a({1});
std::vector<int> b({1,1,1});
// Outputs 'false'
std::cout << std::boolalpha
<< std::includes(a.begin(), a.end(), b.begin(), b.end()) << '\n';
}
这令人惊讶。我用 libstdc++ 和 libc++ 验证了它,但在我看来,这不太可能是标准库实现中的一个错误,因为它是算法库的一部分。如果这不是std::includes 应该运行的算法,那是什么?
【问题讨论】:
-
这看起来像是缺陷报告的候选。我解释 [first2, last2) 范围内的每个元素都包含在 [first1, last1) 范围内,这意味着您需要
{1,1,1}才能匹配{1,1,1}但它的措辞方式我可以看看为什么您可以期望您的案例有效。 -
更多的是检查 R2 ⊆ R1
-
@Mgetz 但
{1,1,1}的每个元素都包含在{1}中,因为它们都是1。对标准的字面理解允许两种解释恕我直言。 -
@NathanOliver 操作用语是每个元素,这意味着必须表示重复的元素,这是集合和列表之间的区别。标准是使用列表而不是集合。
-
@Mgetz 不是说“R2 中的每个元素都必须在 R1 中有对应的元素”,而是“R2 中的每个元素都必须包含在 R1 中”
标签: c++ language-lawyer c++17 stl-algorithm