std :: unique_ptr constexpr构造函数

时间:2016-07-23 06:23:43

标签: c++ c++11 c++14

如图documentation所示,std::unique_ptr有两个用于空指针的constexpr构造函数:

constexpr unique_ptr();
constexpr unique_ptr( nullptr_t );

我对这两个构造函数有两个问题:

  1. 为什么我们需要两个?我们不能将其声明为:

    constexpr unique_ptr( nullptr_t = nullptr );
    
  2. 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
    

2 个答案:

答案 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)

至于Q1,nullptr_t稍后在N2435中添加command.CommandText = "SET STATISTICS XML ON"; 构造函数,远远于原始提案(N1586)。

添加一个可以在一行中指定的简单重载比尝试聪明更简单,特别是因为[member.functions]已经允许实现使用“聪明”版本,如果他们想要的话。