配置compare函数以使用std :: sort

时间:2012-09-24 04:18:51

标签: c++ stl

假设我有以下片段:

int compareFoo(std::string** a, std::string** b) {
    return (**a).compare(**b);
}

int main() {
    std::string** foo = new std::string*[3];
    foo[0] = new std::string("a");
    foo[1] = new std::string("c");
    foo[2] = new std::string("b");
    sort(foo,foo+3,compareFoo);
    for (int i = 0; i < 3; i++) {
        std::cout << *foo[i] << std::endl; // print acb
    }
}

如果我遗漏了排序的第三个参数(比较),它会根据内存地址给我排序的3个字符串,这不是我想要的。但是我如何参数化 compareFoo 函数,以便它不会比较内存地址。

void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);

cplusplus.com上排序的描述非常模糊,给出的示例很简单。因为它需要 Iterator ,这是否意味着我只使用立式容器?谢谢

4 个答案:

答案 0 :(得分:2)

我会重新考虑是否所有这些指针操作都是你想要的。这不是Java或C#。在C ++中,默认情况下不从免费存储(“堆”)分配。只需自动创建数组并直接存储字符串。换句话说,你最终会得到这样的东西:

#include <algorithm>
#include <string>
int main(){
    std::string foo [] = {
        "a",
        "c",
        "b"
    };
    std::sort(foo, foo + 3);
    for(int i = 0; i < 3; i++){
        std::cout << foo[i] << '\n'; // print abc
    }
}

与您的版本相比,

  • 更快
  • 使用更少的内存(没有额外的指针开销)
  • 不泄漏内存
  • 对熟悉C ++的人来说更具可读性
  • 消除对可能的空指针的任何担忧
  • 需要更少的代码
  • 优化编译器效果更佳

答案 1 :(得分:1)

比较函数需要比较两个项,如果第一项小于第二项,则返回true。在你的情况下,它会像这样工作:

#include <string>
#include <algorithm>
#include <iostream>

using std::sort;

bool compareFoo(std::string* a,std::string* b){
  return *a < *b;
}

int main(){
  std::string** foo = new std::string*[3];
  foo[0] = new std::string("a");
  foo[1] = new std::string("c");
  foo[2] = new std::string("b");
  sort(foo,foo+3,compareFoo);
  for(int i=0;i<3;i++){
    std::cout << *foo[i] << std::endl; 
  }

  // Remember to delete things that you dynamically allocate.
  delete foo[0];
  delete foo[1];
  delete foo[2];
  delete [] foo;
}

答案 2 :(得分:1)

std :: sort有三件事:

  1. 表示开始的随机访问迭代器
  2. 表示结束的随机访问迭代器
  3. 一个接受两件事并比较它们以返回结果的函数
  4. 因此,这意味着它可以使用随机访问迭代器模板之后的任何内容。即指针,因此数组应该可以正常工作。

    但是对于您当前的代码,您解除引用一个级别太远,请尝试此

    #include <string>
    #include <algorithm>
    #include <iostream>
    
    using std::sort;
    
    bool compareFoo(std::string a,std::string b){
      return *a < *b; //note the difference
    }
    
    int main(){
      std::string* foo = new std::string[3];
      foo[0] = std::string("a");
      foo[1] = std::string("c");
      foo[2] = std::string("b");
      sort(foo,foo+3,compareFoo);
      for(int i=0;i<3;i++){
        std::cout << *foo[i] << std::endl;
      }
    }
    

    但是请注意,在这种情况下我们不需要提供比较功能,该功能会自动使用&lt;操作

答案 3 :(得分:0)

bool compareFoo(std::string * lhs, std::string * rhs)
{
    return *lhs < *rhs;
}
  

因为它需要一个迭代器,这是否意味着我只能使用支架   容器

没有。迭代器是一个概念。指针符合迭代器概念的要求,因此它是一个迭代器。