【问题标题】:std::unique_ptr constexpr constructorsstd::unique_ptr constexpr 构造函数
【发布时间】:2016-07-23 06:23:43
【问题描述】:

如图herestd::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
    

【问题讨论】:

  • 链接回同一个问题
  • LOL 复制/粘贴失败。但是 oldrinb 的答案链接到我要链接的那个。

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


【解决方案1】:

对于 (1),考虑它确保无参数构造函数 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

【讨论】:

    【解决方案2】:

    至于 Q1,nullptr_t 构造函数是后来在 N2435 中添加的,远在原始提案 (N1586) 之后。

    添加一个可以在一行中指定的简单重载比尝试聪明得多,尤其是 [member.functions] 已经允许实现在需要时使用“聪明”版本。

    【讨论】:

    • 因此,标准中指定的当前两个 ctor 在功能上应该与我的问题中的那个相同,对吗?
    猜你喜欢
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多