How does shared_ptr<> safely allow casting to bool?
I was looking into how std::tr1::shared_ptr<>
开发者_如何学运维 provides the ability to cast to bool. I've got caught out in the past when trying to create a smart pointer that can be casted to bool as the trivial solution, ie
operator bool() {
return m_Ptr!=0;
}
usually ends up being implicitly castable to the pointer type (presumably by type promotion), which is generally undesirable. Both the boost and Microsoft implementations appear to use a trick involving casting to an unspecified_bool_type()
. Can anyone explain how this mechanism works and how it prevents implicit casting to the underlying pointer type?
The technique described in the question is the safe bool idiom.
As of C++11, that idiom is no longer necessary. The modern solution to the problem is to use the explicit
keyword on the operator:
explicit operator bool() {
return m_Ptr != nullptr;
}
The trick works like this. You define all this inside your smart pointer type (in this case, shared_ptr
):
private:
struct Tester
{
Tester(int) {} // No default constructor
void dummy() {}
};
typedef void (Tester::*unspecified_bool_type)();
public:
operator unspecified_bool_type() const
{
return !ptr_ ? 0 : &Tester::dummy;
}
ptr_
is the native pointer inside the smart pointer class.
As you can see, unspecified_bool_type
is a typedef
to a type that cannot be accessed by any external code, since Tester
is a private struct. But calling code can use this (implicit) conversion to a pointer type and check whether it is null or not. Which, in C++, can be used as a bool
expression.
Usually what it returns is a member pointer. Member pointers can be treated like a bool
but don't support many of the implicit conversions which bool
does.
精彩评论