2013-02-17 2 views
5

У меня возникла небольшая проблема с поиском элемента в векторе shared_ptr.Поиск элемента в контейнере shared_ptr?

Вот что я закончил с:

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; 
} 

Однако я не сумел сделать это с std::find или даже std::find_if. Есть ли более C++-совместимый способ достичь этого?

EDIT: Это код, у меня есть после ответа:

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(); 
} 
+0

Так что вы ищете 'shared_ptr' к конкретному _raw pointer_? –

+0

В качестве побочного примечания, если вам нужно найти элементы в контейнере, тогда вектор <> не должен быть вашим контейнером выбора. Вы получите намного лучшую производительность с упорядоченным (отсортированным) контейнером – eladidan

+0

Да, 'std :: set' приходит на ум. – user1095108

ответ

6

Try:

std::find_if(blocks.begin(), blocks.end(), 
    [block](std::shared_ptr<Block> const& i){ return i.get() == block; }); 
+3

Вам нужно проверить, не является ли это 'blocks.end()', чтобы увидеть, находится ли он в векторе. – Xymostech

1

На основе ответов и комментариев от других, здесь полностью рабочий образец из ideone:

#include <vector> 
#include <memory> 
#include <algorithm> 
#include <iostream> 

using namespace std; 

struct Block 
{ 
    bool in_container(const vector<shared_ptr<Block>>& blocks) 
    { 
     auto end = blocks.end(); 
     return end != find_if(blocks.begin(), end, 
           [this](shared_ptr<Block> const& i) 
            { return i.get() == this; }); 
    } 
}; 

int main() 
{ 
    auto block1 = make_shared<Block>(); 
    auto block2 = make_shared<Block>(); 

    vector<shared_ptr<Block>> blocks; 
    blocks.push_back(block1); 

    block1->in_container(blocks) ? 
     cout << "block1 is in the container\n" : 
     cout << "block1 is not in the container\n"; 

    block2->in_container(blocks) ? 
     cout << "block2 is in the container\n" : 
     cout << "block2 is not in the container\n"; 

    return 0; 
} 

Вот вывод:

block1 is in the container 
block2 is not in the container 
+0

спасибо за полный компилируемый и рабочий образец! – bquenin

+0

Нет проблем. Я вижу, что вы тоже пришли к ответу. –

1

Еще проще:

bool contains(Block* block) { 
    return std::any_of(blocks.cbegin(), blocks.cend(), 
        [block](std::shared_ptr<Block> const& i) { return i.get() == block; }); 
} 
Смежные вопросы