C ++中的显式默认构造函数17

时间:2017-05-24 23:48:27

标签: c++ c++17 default-constructor explicit-constructor

在C ++ 17中,标准库中的空标记类型现在具有标记为explicit的默认构造函数,并且也是= default。例如,std::piecewise_construct_t现在定义为

struct piecewise_construct_t { explicit piecewise_construct_t() = default; };

我的问题很简单,这是C ++ 14改变的原因是什么?明确默认的显式默认构造函数(!)对于空类是什么意思?

(为了避免被标记为欺骗:this question从2010年开始询问显式默认构造函数的用途,但那是在C ++ 11之前和很久以前的事情,所以事情可能已经发生了变化。{ {3}}更新,但答案似乎表明无论是否存在默认构造函数,都会执行聚合初始化,因此我很好奇最新标准中此更改的原因。)

1 个答案:

答案 0 :(得分:16)

图书馆变更的理由是LWG 2510 "Tag types should not be DefaultConstructible"

  

std::experimental::optional由于某些原因,指定其nullopt类型不是DefaultConstructible。它的标签类型in_place_t没有这样做,标准类型的标准也不适用。结果证明非常不幸,请考虑以下事项:

#include <memory>
#include <array>

void f(std::array<int, 1>, int) {} // #1
void f(std::allocator_arg_t, int) {} // #2

int main()
{
  f({}, 666); // #3
}
     

#3的电话不明确。更糟糕的是,如果超载#1被删除,则呼叫工作正常。标记类型的全部要点是它需要在调用中提及或者它需要是转发参数,因此能够构造类似的标记类型是没有意义的。

LWG问题与CWG 1518 "Explicit default constructors and copy-list-initialization"并行发展,具有有用的背景。