【问题标题】:weak_ptr's weird copy constructorsweak_ptr 奇怪的复制构造函数
【发布时间】:2011-08-12 00:00:14
【问题描述】:

以下是两个weak_ptr 的构造函数: http://msdn.microsoft.com/en-us/library/bb982126.aspx

weak_ptr(const weak_ptr&);

template<class Other>
weak_ptr(const weak_ptr<Other>&);

实际代码(来自memory):

weak_ptr(const weak_ptr& _Other)
{   // construct weak_ptr object for resource pointed to by _Other
    this->_Resetw(_Other);
}

template<class _Ty2>
weak_ptr(const weak_ptr<_Ty2>& _Other,
         typename enable_if<is_convertible<_Ty2 *, _Ty *>::value,
         void *>::type * = 0)
{   // construct weak_ptr object for resource pointed to by _Other
    this->_Resetw(_Other);
}

Q1:为什么顶部的复制构造函数还在那里?看起来底部的一个占每个案例(包括顶部的一个)。它甚至被调用吗?如果他们不包括它,底部的会取代它吗?

Q2:底部(模板化)构造函数的第二个参数发生了什么。我想我了解 SFINAE 方面,但我不明白为什么::type 后面有一个额外的 *

【问题讨论】:

  • @Hans,那为什么不修复缩进呢?

标签: c++ c++11 shared-ptr weak-ptr


【解决方案1】:

Q1) 如果您不编写复制构造函数,编译器会为您生成一个,这不是您想要的。模板化转换构造函数不算在内。

Q2) 记住shared_ptr&lt;T&gt; 就像T*,必须在指针级别检查可转换性。如果T* 可转换为U*,那么您应该能够将一个分配给另一个。想想指向基址的指针。 [对不起,这不是你问的。] 最后的参数类型只需要存在,但我们也不想指定参数本身。构成我们还可以为其提供默认参数的类型的通用方法是指针。简而言之,我们需要使函数依赖于可能存在或不存在的类型,但实际上并不要求用户知道这一点。

【讨论】:

  • 如果*=0 之前不存在,那么它仍然是成功的 void* 类型。额外的 * 不是使它成为 void**,但是在这种情况下,他们为什么不写 void** 而不是 void* 呢?还有,为什么他们不写 nullptr 而不是 0,这是一个错误吗?
  • @Dave:你没有使用nullptr,这只是一个可选的新功能。无论如何,我不确定您实际上为什么需要双指针,也许这只是他们的房屋风格,总是通过指针使用 SFINAE,而在这种情况下,他们恰好使用 void* 作为内部类型。 GCC 根本不通过函数参数来做到这一点,而是使用默认模板参数来触发替换失败,运行时成本为零。
  • 哈哈。我刚刚写了一个基于 _Ptr_Base 的类似 weak_ptr 的东西,如果我们正在谈论的第二个 * 不存在 VS 说... Error 1 error C1001: An internal error has occurred in the compiler. 所以,这就是它存在的原因。哈。
  • @Dave:很好。谁知道这个库有什么编译器特性……我更担心的是构造函数的签名与记录的签名不同!
【解决方案2】:

关于 Q1:模板化构造函数永远不是“复制构造函数”,即使它设法复制。如果没有用户定义的“拷贝构造函数”,那么编译器会根据需要生成一个。

Re Q2:第二个参数,一个默认为0的指针,只是为了有一个地方放置enable_if。您可以在 Boost 文档中找到更多相关信息(如果我没记错的话)。

干杯,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-02
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    相关资源
    最近更新 更多