I have a simple class containing a vector of shared pointers:
class Bar {
public:
/* stuff */
private:
std::vector<std::shared_ptr<Foo>> foos;
};
I wish to expose my foos
through a getFoos()
function, that would not share the ownership of the objects. One way to do so would be:
std::vector<std::reference_wrapper<Foo>> Bar::getFoos() const {
std::vector<std::reference_wrapper<Foo>> fooRefs;
fooRefs.reserve(foos.size());
for (auto& ptr : foos) {
fooRefs.push_back(std::ref(*ptr));
}
return fooRefs;
}
but that's pretty ugly. Also, I'll most likely need to cache the results since this function gets called pretty often. More complexity, more ugliness.
Is there a cleaner/better way to deal with this issue?
I would expose the Foo
by index and also give the possibility to obtain iterators to them
class Bar {
public:
class FooIt {
// Add typedefs for category etc
std::vector<std::shared_ptr<Foo>>::iterator it; // maybe template on this to easily provide the const overload too
public:
Foo& operator*() const {
return **it;
}
// write Functions to expose ++ etc of it
};
FooIt begin() {
return FooIt{begin(foos)};
}
FooIt end() {
retuen FooIt{end(foos)};
}
// Enables ranged for over Bar, only do if that makes sense for your Bar
Foo& getFoo(size_t index) { // maybe even operator [] if appropriate
return foos[index];
}
};
Of course this is much boilerplate. But actually you can write the FooIt
in a general, templated version if you have this problem at multiple places.