I'm having a little problem with finding an element in a vector of shared_ptr
.
Here is what I ended up with:
std::vector<std::shared_ptr<Block>> blocks;
bool contains(Block* block) {
for (auto i = blocks.begin(); i != blocks.end(); ++i) {
if ((*i).get() == block) {
return true;
}
}
return false;
}
However, I didn't managed to do it with std::find
or even std::find_if
. Is there a more c++ compliant way to achieve this ?
EDIT: This is the code I have after the answer:
bool contains(Block* block) {
auto found = std::find_if(blocks.begin(), blocks.end(), [block](std::shared_ptr<Block> const& i){
return i.get() == block;
});
return found != blocks.end();
}
A shared_ptr may share ownership of an object while storing a pointer to another object. get() returns the stored pointer, not the managed pointer.
In short: Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.
So the best way to return a shared_ptr is to simply return by value: shared_ptr<T> Foo() { return shared_ptr<T>(/* acquire something */); }; This is a dead-obvious RVO opportunity for modern C++ compilers.
In a typical implementation, std::shared_ptr holds only two pointers. So 1000 shared pointers take up 1000 * 2 * sizeof(pointer) bytes of memory. Size of a pointer is 4 bytes on all 32-bit systems that follow ILP32 data model.
Try:
std::find_if(blocks.begin(), blocks.end(),
[block](std::shared_ptr<Block> const& i){ return i.get() == block; });
Even simpler:
bool contains(Block* block) {
return std::any_of(blocks.cbegin(), blocks.cend(),
[block](std::shared_ptr<Block> const& i) { return i.get() == block; });
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With