0

假设我有以下片段:

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
    }
}

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

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

cplusplus.com 上对Sort的描述很模糊,给出的例子很简单。既然它需要一个Iterator,这是否意味着我只使用站立容器?谢谢

4

4 回答 4

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++ 的人来说更具可读性
  • 消除对可能的空指针的任何担忧
  • 需要更少的代码
  • 与优化编译器一起工作更好
于 2012-09-24T04:32:32.460 回答
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;
}
于 2012-09-24T04:22:59.233 回答
1

std::sort 接受三件事:

  1. 表示开始的随机访问迭代器
  2. 代表结束的随机访问迭代器
  3. 一个函数,它接受两件事并比较它们以返回它们的结果

所以这意味着它可以与任何遵循随机访问迭代器模板的东西一起工作。即指针,因此数组应该可以正常工作。

但是,使用您当前的代码,您取消引用一个级别太远了,试试这个

#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;
  }
}

但是请注意,在这种情况下,我们不需要提供比较功能,该功能将自动使用 < 运算符

于 2012-09-24T04:23:39.700 回答
0
bool compareFoo(std::string * lhs, std::string * rhs)
{
    return *lhs < *rhs;
}

既然它需要一个迭代器,这是否意味着我只使用站立容器?

不,迭代器是一个概念。指针满足迭代器概念的要求,所以它是一个迭代器。

于 2012-09-24T04:24:14.140 回答