【问题标题】:Constructors : difference between defaulting and delegating a parameter构造函数:默认和委托参数之间的区别
【发布时间】:2014-09-05 22:23:36
【问题描述】:

今天,我偶然发现了 these standard declarationsstd::vector 构造函数:

// until C++14
explicit vector( const Allocator& alloc = Allocator() );
// since C++14
vector() : vector( Allocator() ) {}
explicit vector( const Allocator& alloc );

这种变化可以在大多数标准容器中看到。一个稍微不同的例子是std::set

// until C++14
explicit set( const Compare& comp = Compare(),
              const Allocator& alloc = Allocator() );
// since C++14
set() : set( Compare() ) {}
explicit set( const Compare& comp,
              const Allocator& alloc = Allocator() );

这两种模式有什么区别,它们的(缺点)优点是什么?
它们是严格等价的吗?编译器会从第一个生成类似于第二个的东西吗?

【问题讨论】:

  • 你说的是“STL”容器。您是指标准本身规定的这些标准库容器成员函数的签名,还是某些特定实现的代码?
  • @LightnessRacesinOrbit 我的意思是前者:我假设这些函数的签名是标准的(en.cppreference.com 说标准发生了变化 - “自 C++14 以来”)。
  • @LightnessRacesinOrbit 我不太明白要编辑什么; “STL”错了吗?对我来说,它是使用模板的标准库的一部分(因此是标准的“模板”库)。还是别的什么?
  • 经过一番研究,我明白你的意思了。但是,“stdlib”标签似乎自动更改为“std”,这也是关于 Ruby 的,并且与“std”标签相比,关注者和问题要少得多。相当误导。
  • 没关系;没有发现 cppreference.com 的链接。这足以表明您在谈论标准签名,而不是一些摇摆不定的不兼容实现代码。

标签: c++ std c++14


【解决方案1】:

区别在于

explicit vector( const Allocator& alloc = Allocator() );

即使在使用默认参数的情况下也是explicit,而

vector() : vector( Allocator() ) {}

不是。 (第一种情况下的explicit 是防止Allocators 隐式转换为vector 所必需的。)

这意味着你可以写

std::vector<int> f() { return {}; }

std::vector<int> vec = {};

在第二种情况下,但不是第一种。

LWG issue 2193

【讨论】:

  • 如果显式关键字被删除,我假设分配器可以隐式转换为向量?
  • 哦,这比我阅读问题时的预期有趣得多。
  • 如果我理解正确,这意味着具有非显式默认构造函数的 any 类型可以“从{} 构造”,即。有点“空元素”的意思。我同意@LightnessRacesinOrbit 的观点,这比预期的要有趣得多。
  • @Alex 我不确定您所说的“无效元素”是什么意思;你得到一个默认的构造对象。完全正常。不同之处在于您可以通过仅从 {} 初始化来完成,而不必显式编写 vector() 或类似的东西。
  • @LightnessRacesinOrbit:对不起,如果不清楚:我的意思是“零元素”。像空容器或字符串、数字零、空指针等。这在模板上下文中可能很有用。此外,能够为任何空容器编写{} 非常有用。
猜你喜欢
  • 2015-02-23
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多