我正在看一本书学习 C++(来自 python 背景)。我写了这个,它有效:
class CatalogueItem
{
public:
CatalogueItem();
CatalogueItem(int item_code, const string &name, const string &description);
~CatalogueItem() {};
bool operator< (const CatalogueItem &other) const;
...
private:
...
};
...
list<CatalogueItem> my_list;
// this is just me playing around
CatalogueItem items[2];
items[0] = CatalogueItem(4, string("box"), string("it's a box"));
items[1] = CatalogueItem(3, string("cat"), string("it's a cat"));
my_list.push_back(items[0]);
my_list.push_back(items[1]);
my_list.sort();
我正在尝试的部分是使用运算符 < 让列表自行排序。
这一切看起来不错,但是 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Operator_Overloading似乎建议避免这样做,这正是书中所说的! (“特别是,不要重载 operator== 或 operator< 只是为了让您的类可以用作 STL 容器中的键;相反,您应该在声明容器时创建相等和比较仿函数类型。”)
我理解“创建相等和比较仿函数类型”是指创建比较函数,如下所示:
bool my_comparison_function(const CatalogueItem &a, const CatalogueItem &b)
{
// my comparison code here
}
这是风格指南所指的吗?
有没有人可以选择哪种方法更“正确”?
J
最佳答案
仿函数类型更像这样:
struct CatalogueItemLessThan
{
bool operator()(const CatalogueItem &a, const CatalogueItem &b)
{
}
};
那么用法看起来像这样:
list<CatalogueItem> my_list;
// this is just me playing around
CatalogueItem items[2];
items[0] = CatalogueItem(4, string("box"), string("it's a box"));
items[1] = CatalogueItem(3, string("cat"), string("it's a cat"));
my_list.push_back(items[0]);
my_list.push_back(items[1]);
my_list.sort(CatalogueItemLessThan());
这样做的主要优点是,允许您将排序与对象本身分离。您现在可以根据需要提供多种类型的排序,并在不同的地方使用它们。 (例如,字符串可以按词法顺序排序,或者不区分大小写,或者“naturally”。
与松散函数相比,使用仿函数的优势在于您可以将参数传递到比较中以修改仿函数的行为方式。
一般来说,Google 风格指南并不是最好的风格指南(恕我直言,尤其是他们对异常(exception)采取异常(exception),但这是另一个讨论)。如果一个对象有明显的排序顺序,我通常会添加一个默认的 operator<
。 .如果稍后,我想添加额外的排序顺序,那么我会添加松散的功能。如果稍后我需要将参数添加到排序顺序中,那么我会将它们变成仿函数。在需要之前增加复杂性是没有意义的。
关于C++ 运算符重载,了解 Google 风格指南,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1561183/