2013-02-28 39 views
5

Vì vậy, tôi có một vector như vậy:Cách tốt nhất để xóa một std :: unique_ptr từ một vector với một con trỏ thô?

std::vector<std::unique_ptr<SomeClass>> myVector; 

Sau đó, tôi có một vector chứa con trỏ nguyên của SomeClass:

std::vector<SomeClass*> myOtherVector; 

Nếu có một yếu tố bên trong myOtherVector nó cũng sẽ được bên myVector, vì vậy tôi muốn xem qua từng phần tử trong myOtherVector và xóa cùng một phần tử khỏi myVector. Sau đó xóa vector. Đây là những gì tôi đã đưa ra:

for(size_t i = 0; i < myOtherVector.size(); i++) 
{ 
    myVector.erase(std::remove(myVector.begin(), myVector.end(), myOtherVector[i]), myVector.end()); 
} 
myOtherVector.clear(); 

này tạo ra một lỗi thời gian biên dịch vì myVector giữ con trỏ độc đáo nhưng tôi đưa ra các chức năng remove() một con trỏ thô. Đây là nơi tôi cần giúp đỡ bởi vì tôi không biết cách thích hợp để giải quyết vấn đề này là gì. Tôi đã thay đổi dòng để:

myVector.erase(std::remove(myVector.begin(), myVector.end(), std::unique_ptr<SomeClass>(myOtherVector[i])), myVector.end()); 

Frist của tất cả điều này là không chính xác bởi vì bây giờ tôi có hai std::unique_ptr s tham khảo cùng một đối tượng. Phần tử bên trong myVector chứa tham chiếu và việc xây dựng con trỏ duy nhất trong dòng trên là một tham chiếu khác. Và tôi thậm chí không biết nếu xây dựng một con trỏ mới để có được cùng một loại là khái niệm đúng cách để đi về việc này. Vì vậy, sau đó tôi đã thay đổi con trỏ duy nhất để con trỏ chia sẻ:

std::vector<std::shared_ptr<SomeClass>> myVector; 
std::vector<SomeClass*> myOtherVector; 

for(size_t i = 0; i < myOtherVector.size(); i++) 
{ 
    myVector.erase(std::remove(myVector.begin(), myVector.end(), std::shared_ptr<SomeClass>(myOtherVector[i])), myVector.end()); 
} 
myOtherVector.clear(); 

Khi tôi chạy các ứng dụng dòng myVector.erase() dẫn đến một lỗi thời gian chạy mà nói "ApplicationName.exe đã gây ra một breakpoint." khi nhấp vào tiếp tục, tôi đã nhận được lỗi xác nhận lỗi.

Vì vậy, rõ ràng là tôi đang làm điều gì đó sai, nhưng tôi không biết điều gì. Cách chính xác để xóa một con trỏ thông minh từ một vector với một con trỏ thô là gì?

+0

bạn đã xem xét đơn giản hóa vấn đề bằng cách người chỉ không duy trì một vector của các con trỏ nguyên để bắt đầu với? –

+0

'std :: unique_ptr' có một thành viên' get' trả về con trỏ sở hữu. –

+1

Uh, một gợi ý. Có một con trỏ thông minh C++ 11 khác gọi là 'std :: shared_ptr'. –

Trả lời

1

Đây là cách tôi sẽ làm điều đó. Hiệu suất có thể được cải thiện, nhưng miễn là nó sẽ không chứng minh là một nút cổ chai cho ứng dụng của bạn, tôi sẽ không bận tâm với điều đó. Thuật toán đơn giản và rõ ràng.

Sử dụng remove_if để chọn lọc xóa khỏi vùng chứa thứ nhất (myVector) tất cả các phần tử trỏ đến đối tượng được trỏ đến bởi các thành phần của vùng chứa thứ hai (myOtherVector); sau đó, nó xóa container thứ hai. Các vị được thực hiện thông qua một hàm lambda:

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

struct SomeClass { /* ... */ }; 

int main() 
{ 
    std::vector<std::unique_ptr<SomeClass>> myVector; 
    std::vector<SomeClass*> myOtherVector; 

    myVector.erase(
     std::remove_if(// Selectively remove elements in the second vector... 
      myVector.begin(), 
      myVector.end(), 
      [&] (std::unique_ptr<SomeClass> const& p) 
      { // This predicate checks whether the element is contained 
       // in the second vector of pointers to be removed... 
       return std::find(
        myOtherVector.cbegin(), 
        myOtherVector.cend(), 
        p.get() 
        ) != myOtherVector.end(); 
      }), 
     myVector.end() 
     ); 

    myOtherVector.clear(); 
} 
3

std::unique_ptr có chức năng thành viên, get, trả về con trỏ được sở hữu.

xem xét như sau:

std::sort(myOtherVector.begin(), myOtherVector.end()); 

myVector.erase(std::remove_if(myVector.begin(), myVector.end(), 
[&](std::unique_ptr<SomeClass> const& p) -> bool 
{ 
    return std::binary_search(myOtherVector.begin(), myOtherVector.end(), 
           p.get()); 
})); 

myOtherVector.clear();  
Các vấn đề liên quan