简体   繁体   English

在 C++ 11 中将 `nullptr` 作为 `std::shared_ptr` 返回是否安全?

[英]Is it safe to return `nullptr` as a `std::shared_ptr` in C++ 11?

Taking the following code snippet as a starting example:以以下代码片段为例:

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

I have thought the return nullptr;我想过return nullptr; statement above is compliant with C++ 11 standard, as the nullptr will be used to construct a null std::shared_ptr when returning to caller, as described at cppreference shared_ptr :上面的语句符合 C++ 11 标准,因为nullptr将用于在返回调用者时构造null std::shared_ptr ,如cppreference shared_ptr 所述

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

However, one of my colleagues keeps insisting that he should go for return shared_ptr<FOO>();然而,我的一位同事一直坚持他应该去return shared_ptr<FOO>(); instead, as he cannot find any official documents nor examples that assigns nullptr to a std::shared_ptr .相反,因为他找不到将nullptr分配给std::shared_ptr任何官方文件或示例。

Am I correct with my understanding?我的理解正确吗? If yes, which document I should show him to prove my oppinion?如果是,我应该给他看什么文件来证明我的意见?

UPDATED 1更新 1

I actually did have a discussion with him, quoting the cppreference shared_ptr , and seems that his concern is now about:我实际上确实与他进行了讨论,引用了cppreference shared_ptr ,似乎他现在关心的是:

That means that using shared_ptr() or shared_ptr(nullptr).这意味着使用 shared_ptr() 或 shared_ptr(nullptr)。 But returning nullptr needs to do casting from nullptr to shared_ptr and it needs a copy constructor.但是返回 nullptr 需要进行从 nullptr 到 shared_ptr 的转换,并且需要一个复制构造函数。

If I understand correctly, his concern is about how a nullptr gets constructed to become a shared_ptr .如果我理解正确的话,他关心的是如何将nullptr构造为shared_ptr Regarding this, the key point is the implicit conversion from nullptr to shared_ptr .关于这一点,关键点是从nullptrshared_ptr的隐式转换。 This should be equivalent to:这应该相当于:

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

 private:
  int a_;
};

A a = 1;

Which document should I look at to clarify the correctness of the above code?我应该看哪个文档来澄清上述代码的正确性?

UPDATED 2更新 2

Looks like Converting constructor can explain the key point here.看起来转换构造函数可以解释这里的关键点。 Thank you all!谢谢你们!

They mean the same thing.他们的意思是一样的。 Here you can even see the generated assembly code is identical: https://godbolt.org/z/odKc4q9ja在这里你甚至可以看到生成的汇编代码是相同的: https : //godbolt.org/z/odKc4q9ja

If you prefer concision and/or dislike nullptr , you can return {} for the same effect.如果您喜欢简洁和/或不喜欢nullptr ,您可以return {}以获得相同的效果。

Your colleague seems to confuse std::shared_ptr<Foo>(nullptr) with std::shared_ptr<FOO>(static_cast<FOO*>(nullptr)) .您的同事似乎将std::shared_ptr<Foo>(nullptr)std::shared_ptr<FOO>(static_cast<FOO*>(nullptr))混淆了。 You are correct: the mentioned overload would be already guarantee that the returned shared_ptr does not hold a resource.你是对的:提到的重载已经保证返回的shared_ptr不包含资源。

But even std::shared_ptr<FOO>(static_cast<FOO*>(nullptr)) is safe.但即使是std::shared_ptr<FOO>(static_cast<FOO*>(nullptr))也是安全的。 From the standard, the preconditions for the ctor:从标准来看,ctor的前提条件:

Preconditions: The expression delete[] p, when T is an array type, or delete p, when T is not an array type, has well-defined behavior, and does not throw exceptions.前提条件:表达式delete[] p,当T 是数组类型时,或delete p,当T 不是数组类型时,具有良好定义的行为,并且不会抛出异常。

delete static_cast<FOO*>(nullptr) meets both conditions: it doesn't do anything. delete static_cast<FOO*>(nullptr)满足两个条件:它不做任何事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM