Обновить комментарий
Если беспокойство было в первую очередь о временном векторе, просто не используйте его. Вы можете использовать qbegin()
/qend()
бесплатные функции из boost::geometry::index
:
std::vector<std::shared_ptr<VeryImportantInfo> > Catalogue::FindIn(float x1, float y1, float x2, float y2)
{
box query_box(point(x1, y1), point(x2, y2));
auto b = bgi::qbegin(rtree, bgi::intersects(query_box)),
e = bgi::qend(rtree);
auto range = boost::make_iterator_range(b, e);
using namespace boost::adaptors;
return boost::copy_range<std::vector<std::shared_ptr<VeryImportantInfo>>>(
range | transformed([](value const& p) { return p.second; }));
}
На самом деле, если известно, что rtree является константой, вы можете даже напрямую вернуть ленивый диапазон и не выделять даже один вектор.
Исходный/старый текст ответа следует ниже:
Вы не можете копировать общие указатели без подсчета ссылок.
Конечно, вы можете изменить пару value
, чтобы она содержала ссылку на shared_ptr, но вместо этого вы могли бы использовать либо необработанные ссылки (std::reference_wrapper), либо weak_ptr
.
std::reference_wrapper<T>
Вот мой взгляд на необработанные ссылки (просто держите свои важные данные поблизости :)):
Жить на Coliru
#include <iostream>
#include <vector>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/index/rtree.hpp>
namespace bg = boost::geometry;
namespace bgi = bg::index;
struct VeryImportantInfo {
float x;
float y;
};
VeryImportantInfo a = { 2, 2 };
VeryImportantInfo b = { 3, 3 };
VeryImportantInfo c = { 4, 4 };
class Catalogue
{
public:
Catalogue() {
rtree.insert(value(point(a.x, a.y), a));
rtree.insert(value(point(b.x, b.y), b));
rtree.insert(value(point(c.x, c.y), c));
}
std::vector<std::reference_wrapper<VeryImportantInfo> > FindIn(float x1, float x2, float y1, float y2);
protected:
using point = bg::model::point<float, 2, bg::cs::cartesian>;
using value = std::pair<point, std::reference_wrapper<VeryImportantInfo> >;
using box = bg::model::box<point>;
boost::geometry::index::rtree< value, bgi::quadratic<16> > rtree;
};
std::vector<std::reference_wrapper<VeryImportantInfo> > Catalogue::FindIn(float x1, float y1, float x2, float y2)
{
box query_box(point(x1, y1), point(x2, y2));
std::vector<value> result_s;
rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));
std::vector<std::reference_wrapper<VeryImportantInfo> > results;
results.reserve(result_s.size());
for(auto& p : result_s) {
results.push_back(p.second);
}
return results;
}
int main() {
Catalogue cat;
for (VeryImportantInfo& vii : cat.FindIn(1,2,3,4))
std::cout << vii.x << ", " << vii.y << "\n";
}
std::weak_ptr<T>
Вот то же самое с weak_ptr<>
. Можно утверждать, что это мало что решает (поскольку подсчет ссылок все еще происходит), но, по крайней мере, требуется меньше работы.
Жить на Coliru
#include <iostream>
#include <memory>
#include <vector>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/index/rtree.hpp>
namespace bg = boost::geometry;
namespace bgi = bg::index;
struct VeryImportantInfo {
float x;
float y;
};
auto a = std::make_shared<VeryImportantInfo>(VeryImportantInfo{2, 2});
auto b = std::make_shared<VeryImportantInfo>(VeryImportantInfo{3, 3});
auto c = std::make_shared<VeryImportantInfo>(VeryImportantInfo{4, 4});
class Catalogue
{
public:
Catalogue() {
rtree.insert(value(point(a->x, a->y), a));
rtree.insert(value(point(b->x, b->y), b));
rtree.insert(value(point(c->x, c->y), c));
}
std::vector<std::weak_ptr<VeryImportantInfo> > FindIn(float x1, float x2, float y1, float y2);
protected:
using point = bg::model::point<float, 2, bg::cs::cartesian>;
using value = std::pair<point, std::shared_ptr<VeryImportantInfo> >;
using box = bg::model::box<point>;
boost::geometry::index::rtree< value, bgi::quadratic<16> > rtree;
};
std::vector<std::weak_ptr<VeryImportantInfo> > Catalogue::FindIn(float x1, float y1, float x2, float y2)
{
box query_box(point(x1, y1), point(x2, y2));
std::vector<value> result_s;
rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));
std::vector<std::weak_ptr<VeryImportantInfo> > results;
results.reserve(result_s.size());
for(auto& p : result_s) {
results.push_back(p.second);
}
return results;
}
int main() {
Catalogue cat;
for (auto& vii_p : cat.FindIn(1,2,3,4))
if (auto vii = vii_p.lock())
std::cout << vii->x << ", " << vii->y << "\n";
}
person
sehe
schedule
07.05.2015