2015-12-30 77 views
0

I'm使用下面的代碼層樓高一種註冊表類刪除一個元素:如何從矢量<shared_ptr>

class MyClass 
{ 
    public: 
     int a; 
     std::string b; 
}; 

class Register 
{ 
    public: 
     std::vector<std::shared_ptr<MyClass>> items; 

     bool registerItem(std::shared_ptr<MyClass> item) 
     { 
      /* 
      * Check if item exists 
      */ 
      auto position = std::find(items.begin(), items.end(), item); 

      if (position != items.end()) 
       return false; 

      items.push_back(item); 

      return true; 
     } 

     bool unregisterItem(std::shared_ptr<MyClass> item) 
     { 
      auto position = std::find(items.begin(), items.end(), item); 

      if (position == items.end()) 
       return false; 

      items.erase(item); 

      return true; 
     } 
}; 


int main() 
{ 
    std::shared_ptr<MyClass> item1 = new MyClass; 

    Register registry; 

    if (!registry.registerItem(item1)) 
     std::cout << "Error registering item1" << std::endl; 
    else 
     std::cout << "Success registering item1" << std::endl; 

    if (!registry.registerItem(item1)) 
     std::cout << "Error unregistering item1" << std::endl; 
    else 
     std::cout << "Success unregistering item1" << std::endl; 
} 

我不能編譯這段代碼,items.erase(item)抱怨error: no matching member function for call to 'erase'

爲什麼我不能刪除我添加的對象。從std::vector中刪除std::shared_ptr的正確方法是什麼?

+4

您擦除*迭代器*,而不是值本身。 –

+0

爲註冊表使用矢量圖可能會變得昂貴;如書面所述,註冊N個項目需要'O(N^2)'時間。另一方面,內部循環速度快,存儲開銷最小。不過,如果你期望'N'很大,你可能想要考慮一個'std :: unordered_set'。 – rici

回答

5

因爲您要使用的迭代器itemsposition),所以:

items.erase(position); 
+0

謝謝。這是我第一次擦除。 – Mendes

2

有兩個聲明可用。 From cppreference

iterator erase (const_iterator position); 
iterator erase (const_iterator first, const_iterator last); 

您嘗試std::vector::erase itsself的項目,而不是迭代器。使用

items.erase(position); 

改爲。

1

你必須調用eraseposition,不item
因爲擦除的迭代器使用

0

你應該通過擦除迭代器不是一個值,刪除std :: shared_ptr沒有什麼特別之處。你也有錯誤的代碼:你註冊項目兩次,而不是在第二次調用註銷它。