Shared_ptr<> 是如何实现的?安全地允许强制转换 bool?

发布于 2024-09-08 14:53:27 字数 324 浏览 1 评论 0 原文

我正在研究 std::tr1::shared_ptr<> 如何提供转换为 bool 的能力。过去,当我尝试创建一个可以转换为 bool 的智能指针作为简单的解决方案时,我就陷入了困境,即

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

通常最终会隐式转换为指针类型(大概是通过类型提升),这通常是不可取的。 boost 和 Microsoft 实现似乎都使用了涉及转换为 unspecified_bool_type() 的技巧。谁能解释一下这种机制是如何工作的以及它如何防止隐式转换为底层指针类型?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

静谧 2024-09-15 14:53:27

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

从 C++11 开始,不再需要该习惯用法。该问题的现代解决方案是在运算符上使用 explicit 关键字:

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

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;
}
娇柔作态 2024-09-15 14:53:27

这个技巧是这样运作的。您可以在智能指针类型中定义所有这些内容(在本例中为 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_type 是一个无法被任何外部代码访问的类型的 typedef,因为 Tester 是一个私有结构。但是调用代码可以使用这种(隐式)转换为指针类型并检查它是否为空。在 C++ 中,可以用作 bool 表达式。

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.

心凉怎暖 2024-09-15 14:53:27

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文