【问题标题】:Is it safe to return `nullptr` as a `std::shared_ptr` in C++ 11?在 C++ 11 中将“nullptr”作为“std::shared_ptr”返回是否安全?
【发布时间】:2021-09-27 19:04:00
【问题描述】:

以如下代码sn-p为例:

template <typename FOO>
std::shared_ptr<FOO> createSharedPtr(bool yesNo) {
  if (!yesNo) {
    return nullptr;
  } else {
    return make_shared<FOO>();
  }
}

我认为上面的return nullptr; 语句符合C++ 11 标准,因为nullptr 将用于构造null std::shared_ptr 当返回调用方时,如cppreference shared_ptr 所述:

constexpr shared_ptr( std::nullptr_t ) noexcept;            (2)

但是,我的一位同事一直坚持他应该改用return shared_ptr&lt;FOO&gt;();,因为他找不到任何官方文件或将nullptr 分配给std::shared_ptr 的示例。

我的理解正确吗?如果是,我应该向他出示什么文件来证明我的意见?

更新 1

我确实和他讨论过,引用了cppreference shared_ptr,看来他现在关心的是:

这意味着使用 shared_ptr() 或 shared_ptr(nullptr)。 但是返回 nullptr 需要从 nullptr 转换为 shared_ptr 并且它需要一个复制构造函数。

如果我理解正确,他关心的是 nullptr 如何构造成 shared_ptr。关于这一点,关键是从nullptr 到shared_ptr 的隐式转换。这应该相当于:

class A {
 public:
  A(int a) : a_(a) {}

 private:
  int a_;
};

A a = 1;

我应该看哪个文档来阐明上述代码的正确性?

更新 2

看来Converting constructor可以在这里解释重点。谢谢大家!

【问题讨论】:

  • 只要给他看从cppreference链接的页面,构造函数(1)和(2)做同样的事情。 1-2) 构造一个没有托管对象的shared_ptr,即空shared_ptr

标签: c++ c++11 shared-ptr smart-pointers implicit-conversion


【解决方案1】:

它们的意思是一样的。在这里你甚至可以看到生成的汇编代码是相同的:https://godbolt.org/z/odKc4q9ja

如果您喜欢简洁和/或不喜欢nullptr,您可以return {} 获得相同的效果。

【讨论】:

  • 我在我的问题中添加了一些内容,你能帮忙吗?
  • 看来你现在已经搞清楚了。
【解决方案2】:

您的同事似乎将std::shared_ptr&lt;Foo&gt;(nullptr) 与std::shared_ptr&lt;FOO&gt;(static_cast&lt;FOO*&gt;(nullptr)) 混淆了。你是对的:上面提到的重载已经保证返回的shared_ptr 不包含资源。

但即使std::shared_ptr&lt;FOO&gt;(static_cast&lt;FOO*&gt;(nullptr)) 也是安全的。从标准来看,ctor的前提条件:

前提条件:表达式delete[] p,当T为数组类型时,或delete p,当T不是数组类型时,行为明确,不抛出异常。

delete static_cast&lt;FOO*&gt;(nullptr) 满足两个条件:它什么都不做。

【讨论】:

  • 有一个微不足道的区别:use_count 可以根据选择的构造函数而有所不同。
猜你喜欢
  • 2020-03-09
  • 1970-01-01
  • 2012-06-02
  • 2013-05-11
  • 1970-01-01
  • 2011-11-04
  • 2021-10-27
  • 2016-10-26
  • 2014-01-05
相关资源
最近更新 更多