Ответ 1
С++ 14 std::set::find
неключевой поиск
Как уже упоминалось на http://en.cppreference.com/w/cpp/container/set/find, С++ 14 добавил два новых API find
:
main.cpp
template< class K > iterator find( const K& x );
template< class K > const_iterator find( const K& x ) const;
которые позволяют вам сделать:
#include <cassert>
#include <set>
class Point {
public:
// Note that there is _no_ conversion constructor,
// everything is done at the template level without
// intermediate object creation.
//Point(int x) : x(x) {}
Point(int x, int y) : x(x), y(y) {}
int x;
int y;
};
bool operator<(const Point& c, int x) { return c.x < x; }
bool operator<(int x, const Point& c) { return x < c.x; }
bool operator<(const Point& c, const Point& d) {
return c.x < d;
}
int main() {
// std::less<> because of:
// https://stackoverflow.com/questions/20317413/what-are-transparent-comparators
std::set<Point, std::less<>> s;
s.insert(Point(1, -1));
s.insert(Point(2, -2));
s.insert(Point(0, 0));
s.insert(Point(3, -3));
assert(s.find(0)->y == 0);
assert(s.find(1)->y == -1);
assert(s.find(2)->y == -2);
assert(s.find(3)->y == -3);
// Ignore 1234, find 1.
assert(s.find(Point(1, 1234))->y == -1);
}
Протестировано на Ubuntu 16.10, g++
6.2.0, с:
g++ -std=c++14 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
Использование собственного класса вместо less<>
Это делает вещи немного более явными и позволяет писать несколько компараторов для каждого класса:
#include <cassert>
#include <set>
class Point {
public:
Point(int x, int y) : x(x), y(y) {}
int x;
int y;
};
struct PointCmpY {
// https://stackoverflow.com/questions/20317413/what-are-transparent-comparators
typedef std::true_type is_transparent;
bool operator()(const Point& lhs, int rhs) const {
return lhs.y < rhs;
}
bool operator()(int lhs, const Point& rhs) const {
return lhs < rhs.y;
}
bool operator()(const Point& lhs, const Point& rhs) const {
return lhs.y < rhs.y;
}
};
int main() {
std::set<Point, PointCmpY> s;
s.insert(Point(1, -1));
s.insert(Point(2, -2));
s.insert(Point(0, 0));
s.insert(Point(3, -3));
assert(s.find(0)->x == 0);
assert(s.find(-1)->x == 1);
assert(s.find(-2)->x == 2);
assert(s.find(-3)->x == 3);
assert(s.find(Point(1234, -1))->x == 1);
}
Смотрите также
- Можно ли использовать элементы другого типа, чем те, которые содержатся в std :: set, для выполнения поиска и удаления?
- Поиск необработанных указателей для наборов unique_ptrs
- индексировать объекты по нескольким ключам: как индексировать и запрашивать контейнеры карты STL по нескольким ключам?
- эффективно реализовать двунаправленную карту: существует ли более эффективная реализация для двунаправленной карты?