假设我有一堂课
class Custom
{
public:
Custom (int x, int y) : x (x), y (x) {}
bool operator() (int a, int b)
{
return a < x && y < b;
}
private:
int x, y;
};
我想要一套
std::set<int, Custom> s
使用Custom的自定义构造函数(即Custom(1,2))
我怎样才能做到这一点?
另外,如果我想在unordered_map中使用它,例如
std::unordered_map<string, std::set<int, Custom>> ht
我怎样才能做到这一点?
在构造集合时需要提供比较器:
using std::unordered_map;
using std::set;
using std::string;
set<int, Custom> s(Custom(10, 20));
// Or:
auto s = set<int, Custom>(Custom(10, 20));
这是因为一旦你开始为集合分配元素就需要有一个比较器,并且因为你的比较器有参数,它需要知道它们是什么
比较器必须是默认构造的,因为调用map["key"]
将默认构造元素(如果它不存在):
class Custom
{
public:
// Add a default constructor
Custom() : x(0), y(0) {}
Custom (int x, int y) : x (x), y (x) {}
bool operator() (int a, int b)
{
return a < x && y < b;
}
private:
int x, y;
};
在这种情况下,可以为比较器提供默认构造函数,因为我们可以重新分配它:
unordered_map<string, set<int, Custom>> map;
map["some key"] = set<int, Custom>(Custom(10, 20));
我们仍然可以使用unordered_map
,但我们必须使用map.at("key")
和map.emplace("key", value)
而不是map["key"]
:
unordered_map<string, set<int, Custom>> map;
set<int, Custom> s(Custom(10, 20));
set<int, Custom> s2(Cunstom(30, 40));
s2.insert(1);
s2.insert(2);
s2.insert(3); // put some stuff in the set
map.emplace("Hello", s); //Inserts the set
map.insert({"Hello", s2}); //Inserts the set as a key-value pair
我们可以使用map.at
获取值:
// This line gets the set at "Hello", and inserts 10 into the set:
map.at("Hello").insert(10);
// If "Hello" isn't in the map, there's an error
我们可以使用map.find("key")
检查地图中是否有东西:
// Get an iterator to the key value pair held by "Hello" in the map:
// An iterator acts like a pointer
auto iterator = map.find("Hello");
if(iterator == map.end()) // Check if we found the thing
{
std::cout << "Couldn't find 'Hello' in the map";
}
else
{
// Get the key from the iterator
string key = iterator->first;
// Get a reference to the value from the iterator
set<int, Custom>& value = iterator->second;
}
std::set
有一个重载的构造函数,它将比较器类的一个实例作为参数。如果比较器类没有默认构造函数(如此处所示),则必须使用该构造函数构造std::set
的每个实例:
std::set<int, Custom> set_instance{ Custom{4,4} };
这个std::set
实例使用Custom{4,4}
作为比较器。该组的不同实例可以使用不同的比较器。
因为这个std::set
没有默认构造函数,所以你不能使用map的[]
操作符,所以你必须做一些工作。 []
将尝试默认构造值类的实例,并且此set不再具有可用的默认构造函数;所以你需要使用find()
或insert()
来明确搜索和/或在地图中插入新值。 C ++ 17添加了一个insert_or_assign()
方法,使这更容易一些。