为什么std :: is_permutation无法在两种不同类型的数据之间起作用?

Shavera

假设我有一个整数和字符串的向量,并且我想比较它们是否具有等效元素,而不考虑顺序。最终,我要问整数向量是否是字符串向量的排列(反之亦然)。我希望能够只调用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.Adaptors.Transformed);
  • 编写自己的std :: is_permutation实现(例如,将示例实现复制到cppreference上);
  • 实际上,请注意,gcc(即libstdc ++)实现并不强制要求值类型相同。它只需要您必须提供的几个签名,因此编写一个多态谓词,例如一个函数对象或一个多态lambda,或者编写可从两种范围值类型转换的参数类型(例如,您的情况是boost::variant<int, string>丑陋的,但可能不是)那么不好)。这是不可移植的,因为另一个实现可能选择执行该要求。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我的分组在两种不同类型的字符串之间不求和正确的值

来自分类Dev

为什么这两种方式的数据绑定不起作用?

来自分类Dev

为什么我收到一个错误,即使在转换字段数据类型后我也无法连接两种不同的数据类型

来自分类Dev

为什么std :: endl的类型推导失败?

来自分类Dev

为什么std :: forward()不演绎类型?

来自分类Dev

为什么std :: copy无法向量化?

来自分类Dev

为什么std :: ostream无法移动?

来自分类Dev

为什么std :: ostream无法移动?

来自分类Dev

为什么std :: copy无法向量化?

来自分类Dev

为什么std :: cout无法正确显示?

来自分类Dev

为什么我的Plotly表达人物不起作用?-“ ValueError:Plotly Express无法处理具有不同类型的列的宽格式数据。”

来自分类Dev

为什么std :: cbegin返回与std :: begin相同的类型

来自分类Dev

为什么我在两种解决方案之间得到了不同的结果图?

来自分类Dev

为什么std :: set_intersection不起作用?

来自分类Dev

为什么std :: string.find()对于“ <”不起作用?

来自分类Dev

为什么这个std :: enable_if不起作用

来自分类Dev

为什么两种输入字符串的方法都起作用?

来自分类Dev

这两种Pig数据类型之间有什么区别?

来自分类Dev

为什么将枚举数组强制转换为两种不同的IEnumerable <T>类型?

来自分类Dev

为什么片段之间有两种导航方式?

来自分类Dev

为什么吊索配置有两种不同的格式

来自分类Dev

为什么矩形有两种不同的阴影

来自分类Dev

启动服务的两种不同方式。为什么?

来自分类Dev

Java递归提供两种不同的结果。为什么?

来自分类Dev

为什么两种计算的结果不同?

来自分类Dev

为什么这两种打印所有被3和5整除的数字在5到50之间的解决方案都起作用?

来自分类Dev

为什么Java有4种不同类型的引用?

来自分类Dev

这两种类型注释之间有何区别?为什么不同?

来自分类Dev

为什么左外连接对 SQL 表中不同类型的属性不起作用?

Related 相关文章

  1. 1

    为什么我的分组在两种不同类型的字符串之间不求和正确的值

  2. 2

    为什么这两种方式的数据绑定不起作用?

  3. 3

    为什么我收到一个错误,即使在转换字段数据类型后我也无法连接两种不同的数据类型

  4. 4

    为什么std :: endl的类型推导失败?

  5. 5

    为什么std :: forward()不演绎类型?

  6. 6

    为什么std :: copy无法向量化?

  7. 7

    为什么std :: ostream无法移动?

  8. 8

    为什么std :: ostream无法移动?

  9. 9

    为什么std :: copy无法向量化?

  10. 10

    为什么std :: cout无法正确显示?

  11. 11

    为什么我的Plotly表达人物不起作用?-“ ValueError:Plotly Express无法处理具有不同类型的列的宽格式数据。”

  12. 12

    为什么std :: cbegin返回与std :: begin相同的类型

  13. 13

    为什么我在两种解决方案之间得到了不同的结果图?

  14. 14

    为什么std :: set_intersection不起作用?

  15. 15

    为什么std :: string.find()对于“ <”不起作用?

  16. 16

    为什么这个std :: enable_if不起作用

  17. 17

    为什么两种输入字符串的方法都起作用?

  18. 18

    这两种Pig数据类型之间有什么区别?

  19. 19

    为什么将枚举数组强制转换为两种不同的IEnumerable <T>类型?

  20. 20

    为什么片段之间有两种导航方式?

  21. 21

    为什么吊索配置有两种不同的格式

  22. 22

    为什么矩形有两种不同的阴影

  23. 23

    启动服务的两种不同方式。为什么?

  24. 24

    Java递归提供两种不同的结果。为什么?

  25. 25

    为什么两种计算的结果不同?

  26. 26

    为什么这两种打印所有被3和5整除的数字在5到50之间的解决方案都起作用?

  27. 27

    为什么Java有4种不同类型的引用?

  28. 28

    这两种类型注释之间有何区别?为什么不同?

  29. 29

    为什么左外连接对 SQL 表中不同类型的属性不起作用?

热门标签

归档