2010-07-07 117 views
21

我正在研究std::tr1::shared_ptr<>如何提供投射到布尔的能力。我想(大概是通过类型提升创建一个智能指针,可以铸造到bool作为平凡解,即shared_ptr <>如何安全地允许转换为bool?

operator bool() { 
    return m_Ptr!=0; 
} 

通常最终被隐式强制转换为指针类型时,过去被抓住了),这通常是不希望的。助推器和微软的实施似乎都使用涉及铸造到unspecified_bool_type()的技巧。任何人都可以解释这种机制如何工作,以及如何防止隐式转换为基础指针类型?

+0

所有优秀的答案,谢谢。很高兴能够给它起一个名字 - 没有遇到过安全的布尔成语。 – 2010-07-07 10:24:20

回答

31

在问题中描述的技术是safe bool idiom

从C++ 11开始,这个习语就不再需要了。现代的解决问题的方法是使用explicit关键字上操作:

explicit operator bool() { 
    return m_Ptr != nullptr; 
} 
+0

呵呵,我知道安全的bool习惯用法,并且最近发现了'explicit'转换运算符,但我不知道这个lil'null_ptr' thingy。谢谢:) – 2010-07-07 09:12:18

3

它通常返回的是一个成员指针。成员指针可以像bool一样对待,但不支持bool所做的许多隐式转换。

4

的诀窍是这样的。您可以定义这一切你的智能指针类型的内部(在这种情况下,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_是智能指针类中的原生指针。

正如你所看到的,unspecified_bool_typetypedef到无法通过任何外部代码访问的类型,因为Tester是一个私人结构。但调用代码可以使用这种(隐式)转换为指针类型并检查它是否为空。在C++中,它可以用作bool表达式。

+0

## ModelId是怎么回事? – kennytm 2010-07-07 08:55:30

+0

@KennyTM:对不起,刚刚删除了。 – Gorpik 2010-07-07 08:55:58

+1

您需要为'Tester :: unspecified_bool_type'提供'!='和'=='的实现,否则您将允许在类的实例之间进行无意义的比较编译。 – 2010-07-07 08:59:59

相关问题