Nếu mục tiêu là thời gian không đổi để tra cứu, tôi không nghĩ rằng có một giải pháp. std::unordered_set<std::unique_ptr<MyClass>>::find
yêu cầu số std::unique_ptr<MyClass>
làm đối số. Bạn sẽ phải thay đổi vùng chứa hoặc thay đổi loại được chứa.
Một khả năng có thể để thay thế std::unique_ptr
với std::shared_ptr
, và thay đổi còn lại của mã sao cho tất cả MyClass
được đưa vào một shared_ptr ngay sau khi họ được tạo ra, và chỉ được thao tác thông qua con trỏ chia sẻ. Về mặt logic, điều này có lẽ mạch lạc hơn: unique_ptr
khá nhiều ngụ ý (theo tên của nó, cũng như ngữ nghĩa của nó) rằng có không phải là con trỏ khác cho đối tượng. Mặt khác, bạn có thể không thể sử dụng shared_ptr, nếu ví dụ: MyClass
có con trỏ đến khác MyClass
, có thể tạo chu trình.
Ngược lại, nếu bạn có thể chấp nhận truy cập O (lg n), chứ không phải là truy cập thường xuyên (sự khác biệt thường không trở thành đáng chú ý cho đến khi các bảng là khá lớn), bạn có thể sử dụng một std::vector<MyClass>
, sử dụng std::lower_bound
để giữ nó được sắp xếp. Không giống như std::unordered_set<>::find
, std::lower_bound
không không yêu cầu giá trị đích phải có cùng loại với số value_type
của chuỗi; tất cả các bạn phải làm là để đảm bảo rằng họ có thể so sánh, nói bằng cách cung cấp một đối tượng Compare
dọc theo dòng:
class MyClassPtrCompare
{
std::less<MyClass const*> cmp;
public:
bool operator()(std::unique_ptr<MyClass> const& lhs,
std::unique_ptr<MyClass> const& rhs) const
{
return cmp(lhs.get(), rhs.get());
}
bool operator()(MyClass const* lhs,
std::unique_ptr<MyClass> const& rhs) const
{
return cmp(lhs, rhs.get());
}
bool operator()(std::unique_ptr<MyClass> const& lhs,
MyClass const* rhs) const
{
return cmp(lhs.get(), rhs);
}
bool operator()(MyClass const* lhs,
MyClass const* rhs) const
{
return cmp(lhs, rhs);
}
};
Insertion có thể liên quan đến một số lần di chuyển, nhưng di chuyển một std::unique_ptr
nên khá rẻ và địa điểm được cải thiện của giải pháp này có thể bù đắp thời gian chạy bổ sung chi phí mà nó áp đặt theo cách khác.
Nguồn
2013-07-25 08:42:03
Cảm ơn. Tôi không cần phải di chuyển hoặc sao chép bất cứ điều gì, vì vậy unique_ptr là okay. Tôi chỉ cần để cho người gọi cho tôi một con trỏ thô, và tôi cần phải kiểm tra nếu một unique_ptr phù hợp tồn tại trong bộ này. – cfa45ca55111016ee9269f0a52e771
'unique_ptr' rõ ràng không phải là những gì bạn cần, vì bạn rõ ràng có các con trỏ khác cho đối tượng. –
Chủ sở hữu của unique_ptr là chủ sở hữu duy nhất của bộ nhớ và tất cả những người khác chỉ giữ tham chiếu. Tôi có thể sử dụng chia sẻ :: ptr trong chủ sở hữu và weak_ptr ở khắp mọi nơi khác, nhưng sau đó mỗi đối tượng được tham chiếu bởi một shared_ptr duy nhất. Tôi không cần chia sẻ, chỉ cần một chủ sở hữu duy nhất – cfa45ca55111016ee9269f0a52e771