假设我有一个整数和字符串的向量,并且我想比较它们是否具有等效元素,而不考虑顺序。最终,我要问整数向量是否是字符串向量的排列(反之亦然)。我希望能够只调用is_permutation,指定一个二进制谓词,使我能够比较两者,然后继续生活。例如:
bool checkIntStringComparison( const std::vector<int>& intVec,
const std::vector<std::string>& stringVec,
const std::map<int, std::string>& intStringMap){
return std::is_permutation<std::vector<int>::const_iterator, std::vector<std::string>::const_iterator>(
intVec.cbegin(), intVec.cend(), stringVec.cbegin(), [&intStringMap](const int& i, const std::string& string){
return string == intStringMap.at(i);
});
}
但是尝试编译(在gcc中)会返回一条错误消息,该错误消息可以归结为:
没有匹配的东西:: <lambda(const int&,const string&>)(const std :: _ cxx11 :: basic_string&,const int&)
看看它如何切换lambda的呼叫签名?如果我切换它们,签名将以另一种方式切换自身。
仔细研究此错误,似乎该标准为std :: is_permutation指定了ForwardIterator1和2必须为同一类型。因此,我了解这方面的编译器错误。但是为什么要这样呢?如果我提供一个允许我比较两者的二进制谓词(或者如果我们之前已经定义了两者之间的相等运算符?),那么算法的真正核心不是仅搜索容器1以确保其所有元素都在容器中。在容器2中唯一?
问题是一个元素可以出现多次。这意味着谓词不仅需要将第一个范围的元素与第二个范围的元素进行比较,而且还需要将第一个范围的元素与其自身进行比较:
if (size(range1) != size(range2))
return false;
for (auto const& x1 : range1)
if (count_if(range1, [&](auto const& y1) { return pred(x1, y1); }) !=
count_if(range2, [&](auto const& y2) { return pred(x1, y2); }))
return false;
return true;
由于创建带有两个不同签名的函数对象相对困难,并且传递两个谓词会造成混淆,因此最简单的选择是指定两个范围必须具有相同的值类型。
您的选择是:
boost::variant<int, string>
丑陋的,但可能不是)那么不好)。这是不可移植的,因为另一个实现可能选择执行该要求。本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句