Exception-safe solution with efficient hash-based lookup (so the linear time complexity of std::find_if or std::lower_bound is eliminated) and no transparency restrictions (this is a copy of my answer to a similar question):
/*
* Behaves like an std::unique_ptr that
* does not delete the pointer on destruction
*/
template<typename T>
class bad_ptr
{
private:
std::unique_ptr<T> m_ptr;
public:
// construct from a pointer
bad_ptr(T* ptr) : m_ptr{ptr} { }
// convert to an std::unique_ptr&
operator const std::unique_ptr<T>&() {
return m_ptr;
}
// release the pointer without deleting it
~bad_ptr() {
m_ptr.release();
}
};
Usage:
struct test_struct {
int a;
int b;
};
int main()
{
std::unordered_set<std::unique_ptr<test_struct>> set;
auto raw_ptr = set.insert(std::make_unique<test_struct>(1, 2)).first->get();
// error
// set.erase(raw_ptr);
// works
set.erase(bad_ptr{raw_ptr});
}
So that you get
mySet.erase(bad_ptr{myClass});