如何在c ++中使用我的自定义比较创建一个集合

时间:2014-06-23 05:37:46

标签: c++ set c-strings

有人可以解释一下这个例子here中发生了什么吗?

他们声明如下:

bool fncomp (int lhs, int rhs) {return lhs<rhs;}

然后用作:

bool(*fn_pt)(int,int) = fncomp;
std::set<int,bool(*)(int,int)> sixth (fn_pt)

虽然算法库here

中的排序方法示例

可以这样做:

bool myfunction (int i,int j) { return (i<j); }
std::sort (myvector.begin()+4, myvector.end(), myfunction);

我也不了解以下内容:

struct classcomp {
    bool operator() (const int& lhs, const int& rhs) const
       {return lhs<rhs;}
};

这个关键字运算符(在op。重载中没有跟随运算符)......它的含义是什么?在那里应用的任何操作员都会有这种行为而这个const修饰符......它造成的影响是什么?

我试图按如下方式制作一组C风格的字符串:

typedef struct 
{
   char grid[7];
} wrap;

bool compare(wrap w1, wrap w2)
{
   return strcmp(w1.grid, w2.grid) == -1;
}
set <wrap, compare> myset;

我以为我可以创建一个定义我的排序函数的集合,就像我从算法库中调用sort一样...一旦它没有编译我就去了文档,看到这个语法让我感到困惑。 ..我是否需要声明一个指向函数的指针,就像我在这里粘贴的第一个例子一样?

3 个答案:

答案 0 :(得分:1)

struct classcomp {
    bool operator() (const int& lhs, const int& rhs) const
       {return lhs<rhs;}
};

通过重载函数调用操作符来定义仿函数。要使用功能,您可以这样做:

int main() {
    std::set <wrap, bool (*)(wrap,wrap)> myset(compare);
    return 0;

}

另一种方法是将运算符定义为wrap类的一部分:

struct wrap {
    char grid[7];
    bool operator<(const wrap& rhs) const {
        return strcmp(this->grid, rhs.grid) == -1; 
    }
};

int main() {
    wrap a;
    std::set <wrap> myset;
    myset.insert(a);
    return 0;
}

答案 1 :(得分:1)

你差不多......这是代码的“固定”版本(see it run here at ideone.com):

#include <iostream>
#include <set>
#include <cstring>

using namespace std;

typedef struct 
{
   char grid[7];
} wrap;

bool compare(wrap w1, wrap w2) // more efficient: ...(const wrap& e1, const wrap@ w2)
{
   return strcmp(w1.grid, w2.grid) < 0;
}

set <wrap, bool(*)(wrap, wrap)> myset(compare);

int main() {
    wrap w1 { "abcdef" };
    wrap w2 { "ABCDEF" };
    myset.insert(w1);
    myset.insert(w2);
    std::cout << myset.begin()->grid[0] << '\n';
}
  

“向我解释这个例子中发生了什么”

嗯,关键路线是......

std::set<wrap, bool(*)(wrap, wrap)> myset(compare);

...使用第二个模板参数指定将执行比较的函数类型,然后使用构造函数参数指定函数。 set对象将存储指向函数的指针,并在需要比较元素时调用它。

  

“算法库中排序方法的示例......”

std::sort中的

algorithm非常适用于vector,它们不会在插入元素时自动排序,但可以随时排序。 std::set虽然需要不断维护排序顺序,因为插入新元素,查找和删除现有元素等的逻辑都假定现有元素总是排序。因此,您无法将std::sort()应用于现有的std::set

  

“这个关键字operator(在op。重载中没有跟随运算符)......它的含义是什么?在那里应用的任何运算符都会有这种行为?这个const修饰符..它造成的影响是什么?

可以使用用于调用函数的相同表示法在对象上调用

operator()(...),例如:

classcomp my_classcomp;
if (my_classcomp(my_int1, my_int_2))
    std::cout << "<\n";

正如您所看到的,my_classcomp被“调用”,好像它是一个函数。 const修饰符意味着即使my_classcomp被定义为const classcomp,上面的代码仍然有效,因为比较函数不需要修改classcomp对象的任何成员变量(如果有任何数据成员)。

答案 2 :(得分:0)

你几乎回答了你的问题:

bool compare(wrap w1, wrap w2)
{
   return strcmp(w1.grid, w2.grid) == -1;
}

struct wrap_comparer
{
    bool operator()(const wrap& _Left, const wrap& _Right) const
    {
        return strcmp(_Left.grid, _Right.grid) == -1;
    }
};

// declares pointer to function
bool(*fn_pt)(wrap,wrap) = compare;
// uses constructor with function pointer argument
std::set<wrap,bool(*)(wrap,wrap)> new_set(fn_pt);
// uses the function directly
std::set<wrap,bool(*)(wrap,wrap)> new_set2(compare);
// uses comparer
std::set<wrap, wrap_comparer> new_set3;

std :: sort可以使用函数指针或函数对象(http://www.cplusplus.com/reference/algorithm/sort/),以及std :: set构造函数。

函数签名后的

const修饰符意味着函数不能修改对象状态,因此可以在const对象上调用。