【问题标题】:Sort function from standard library gives an error using an iterator标准库中的排序函数使用迭代器给出错误
【发布时间】:2020-05-26 01:22:44
【问题描述】:

我对 C++ 语言比较陌生,并尝试从标准命名空间中定义的算法库中实现排序功能并直接使用 std::sort。 使用 sort 对向量进行排序的常见结构是使用迭代器和比较函数给出的。

考虑向量v as {4,3,5,9},排序后它看起来像{9,5,4,3}. 举个例子

 std::sort(v.begin(),v.end(),a>b)

所以,我想使用这种方法根据我的 A* 搜索算法的启发式值对节点列表进行排序。启发式基本上是添加节点对象的 2 个属性,我必须对这个向量进行排序操作节点,我想使用

open_list.begin() and open_list.end() as my iterators 

使用我的比较函数作为 std::sort() 函数的第三个参数,这是实际的实现:

std::sort(open_list.begin(),open_list.end(),open_list.begin()->g_value + open_list.begin()->h_value > open_list.end()->g_value + open_list.end()->h_value ); 

在这里,我基本上是添加 h 和 g 值,它们是对象节点的属性和 open_list 是指向节点的指针向量。我觉得我的实现是正确的,但它给我带来了一个奇怪的错误,如下所示:

/home/piyushkumar/CppND-Route-Planning-Project/src/route_planner.cpp:65:93:错误:在'((RoutePlanner)中请求成员'h_value' this)->RoutePlanner::open_list.std::vector::begin().__gnu_cxx::__normal_iterator >::operator->()',它是指针类型'RouteModel::Node*'(也许你的意思是使用'->'?) std::sort(open_list.begin(),open_list.end(),open_list.begin()->g_value + open_list.begin()->h_value > open_list.end()->g_value + open_list.end()- >h_value );

关于错误的一些说明: RouteModel 是一个类,Node 继承自该类。为什么这个简单的比较函数作为第三个参数会失败,并说你应该使用->,我已经用它从 Node 对象中检索 g_value 和 h_value 的值。

任何帮助和线索将不胜感激。

【问题讨论】:

  • 您所做的一切都不是潜在有效的 C++。您是否要求我们将任何语言翻译成 C++?

标签: c++ sorting c++17


【解决方案1】:

好的,让我们一一解决。

首先关于您的错误消息。您的向量存储指针,请记住a->b 等同于(*a).b,因此open_list.begin()->h_value 等于open_list.front().h_value,并且指针显然没有成员变量。引用成员变量需要写(*open_list.begin())->h_value。此外,取消引用 .end() 会立即为您提供未定义的行为。要访问std::vector 的最后一个元素,请使用.back() 而不是*(you_vector.end())。 (记得事先检查向量不为空!否则你会再次陷入未定义的行为:))

其次,您对如何使用std::sort 的想法是错误的。要按照您选择的“标准”对元素范围进行排序,sort 的前两个参数提供有关范围的信息,第三个参数是您的“标准”,因此它必须是“可调用的”,并且需要两个参数并告诉std::sort 第一个参数是否应该排在第二个参数之前。因此,要对v进行降序排序,您需要通过以下方式调用std::sort

std::sort(v.begin(), v.end(), [](int a,int b)->bool{ return a > b;});

这里,第三个参数是一个 lambda 表达式,如果你不知道它是什么鬼,google 帮助你。 (仅供参考,callable 不一定是 lambda 表达式,它也可能是一个函数或仿函数(也称为函数对象),但我个人认为 lambda 是这里最清晰的。)

我不会给你排序你的open_list所需的语句,你可以用它来检查你是否已经弄清楚事情是如何工作的。享受学习。

【讨论】:

  • 顺便说一句,我真的认为在进入操场之前应该阅读(而不是浏览)一些有关 C++ 的书籍,否则您将不知道自己在做什么。
  • 你有什么适合初学者的书推荐吗?
  • @PiyushBhuva C++ 入门。它可以帮助您理解一些非常基本的编程概念,非常适合完全不熟悉编程或 C++ 的人。我的一些朋友认为它太详细了,但我认为这对初学者来说不是问题。
【解决方案2】:

好吧,这里就不多说了。

std::sort 的第三个参数是一个“可调用”(就像函数指针一样),std::sort 调用它来比较序列中的两个元素。它需要获取序列的两个元素(通常是 const & 并返回一个布尔值。

您的示例 std::sort(v.begin(),v.end(),a>b) 将不起作用,因为 a>b 不可调用。

您的“真实”代码也存在同样的问题。

std::sort(open_list.begin(),
          open_list.end(),
              open_list.begin()->g_value + open_list.begin()->h_value >
              open_list.end()->g_value +   open_list.end()->h_value ); 

那个大表达式是可调用的,而就是编译器抱怨的原因。

另外,FWIW,open_list.end() 是序列中“结束后的一个”位置的迭代器,并且取消引用它(就像您在 open_list.end()->g_value 中所做的那样)是未定义的行为,因为那里没有元素。

请参阅cppreference 了解更多信息。

【讨论】:

    猜你喜欢
    • 2022-01-20
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多