如图documentation所示,std::unique_ptr
有两个用于空指针的constexpr
构造函数:
constexpr unique_ptr();
constexpr unique_ptr( nullptr_t );
我对这两个构造函数有两个问题:
为什么我们需要两个?我们不能将其声明为:
constexpr unique_ptr( nullptr_t = nullptr );
constexpr
真的有用吗?我尝试在我的代码中执行此操作,但它没有编译(g ++ 6.1.0,-std=c++14
):
constexpr std::unique_ptr<int> p;
// error: the type 'const std::unique_ptr<int>' of constexpr variable 'p'
// is not literal because 'std::unique_ptr<int>' has a non-trivial destructor
答案 0 :(得分:14)
对于(1),考虑它确保no-arg构造函数unique_ptr()
和空指针构造函数unique_ptr(nullptr_t)
具有相同的编译时保证,即两者都是constexpr
。我们可以看到§20.8.1.2中的区别:
constexpr unique_ptr() noexcept;
explicit unique_ptr(pointer p) noexcept;
...
constexpr unique_ptr(nullptr_t) noexcept
: unique_ptr() { }
为什么两者没有合并为一个具有默认值的构造函数,可能是历史偶然事件。
关于(2),尽管有一个非平凡的析构函数,为什么我们应该关心constexpr
,考虑the answer given here:
constexpr
构造函数可用于常量初始化,作为静态初始化的一种形式,保证在任何动态初始化发生之前发生。例如,给定全局
std::mutex
:std::mutex mutex;
在一致的实现中(读取:不是MSVC),其他对象的构造函数可以安全地锁定和解锁
mutex
,因为std::mutex
的构造函数是constexpr
。
答案 1 :(得分:9)