我今天偶然发现了一件非常微妙的事情。这是一些代码来演示:
final String searchURL = "https://www.amazon.com/s/?field-keywords=";
String keywords = "something";
view.loadUrl(searchURL + keywords);
输出为:
#include <set>
#include <iostream>
class MyClass {
private:
int id = -1;
public:
MyClass() {}
MyClass(int _id) : id(_id) {}
bool operator() (const MyClass& instance1, const MyClass& instance2) const {
std::cout << id << std::endl;
std::cout << instance1.id << std::endl;
std::cout << instance2.id << std::endl;
return true;
}
};
int main(int argc, char *argv[])
{
std::set<MyClass, MyClass> classSet;
classSet.insert(MyClass(1));
classSet.insert(MyClass(2));
return 0;
}
当我使用设置-1
2
1
值的专用构造函数创建所有类实例时,我很惊讶id
的值为-1。显然,C ++使用标准构造函数创建了一些虚拟实例。
我的问题是:
this->id
是1还是2)?还是我总是必须在内部使用标准构造函数为C ++准备我的类?答案 0 :(得分:5)
编写std::set<MyClass, MyClass>
时,它声明需要使用类MyClass
的实例来比较集合中包含的每两个实例。
如果std::set
的比较器是默认可构造的,则该集合将创建一个实例进行比较(出于明显的原因)。它将使用您提供的默认构造函数,该构造函数会将id
设置为您提供的默认成员初始化程序。
如果要删除默认的构造函数,则该程序将不会生成,因为std::set
将要求您在设置对象初始化时提供一个比较器实例。
答案 1 :(得分:4)
您的比较器函数是一个非静态成员函数,这意味着它需要一个对象被调用。 std::set
会创建这样的实例,因为您可以通过提供MyClass
类型作为模板参数来平铺它。
我的建议是改用非成员operator<
函数重载。
class MyClass {
public:
...
// the `friend` keyword makes this function a non-member function
friend bool operator< (const MyClass& instance1, const MyClass& instance2) {
std::cout << instance1.id << std::endl;
std::cout << instance2.id << std::endl;
return instance1.id < instance2.id;
}
};
...
// No comparator type needed
std::set<MyClass> classSet;