为什么 ctor 中的 std::initializer_list 没有按预期运行?

xmllmx
#include <vector>

int main()
{
    auto v = std::vector{std::vector<int>{}};
    return v.front().empty(); // error
}

在线演示

然而,根据 Scott Meyers 的Effective Modern C++(强调原文):

但是,如果一个或多个构造函数声明了一个类型为 的参数std::initializer_list,则使用花括号初始化语法的调用强烈倾向于采用 的重载std::initializer_lists强烈如果编译器有任何方法可以将使用花括号初始化器的调用解释为采用 a 的构造函数std::initializer_list,则编译器将采用该解释。

所以,我认为std::vector{std::vector<int>{}};应该产生一个对象std::vector<std::vector<int>>而不是std::vector<int>.

谁错了?为什么?

戴维斯鲱鱼

Meyers 大部分是正确的(例外是T{}如果存在默认构造函数则值初始化),但他的陈述是关于重载决议的。这发生在 CTAD 之后,CTAD 选择要使用的(以及构造函数集)。

CTAD 不“偏爱”初始化列表构造函数,因为它更喜欢复制不是包装可嵌套模板,例如std::vectorstd::optional(可以使用推导指南覆盖它,但标准库使用默认值,正如人们所期望的那样。)这在一定程度上可以防止创建奇怪的类型,例如std::optional<std::optional<int>>,但它使泛型代码更难编写,因为它提供

template<class T> void f(T x) {
  std::vector v{x};
  // …
}

一种以不规则非注入方式取决于其论点类型的含义特别是,v可能std::vector<int>T=int或与T= std::vector<int>,尽管是std::vector<std::deque<int>>if T= std::deque<int>不幸的是,基于其他一些类型计算一种类型的工具在通用上下文中不可用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么C ++ 11中的std :: initializer_list重载了std :: begin()和std :: end()?

为什么`std :: initializer_list`没有定义为文字类型?

为什么在VS2019中初始化std :: initializer_list似乎失败

为什么要通过右值引用还是按值来获取std :: initializer_list?

在clang中返回std :: initializer_list

为什么Clang无法优化std :: initializer_list?

为什么std :: initializer_list不是内置语言?

为什么不首选std :: initializer_list转换?

为什么必须复制std :: initializer_list的元素?

为什么std :: initializer_list复制项目?

为什么std :: min仅支持initializer_list?

带有 std::thread 的 std::initializer_list

检查元素是否在std :: initializer_list中

构造函数中的std :: initializer_list转换

Visual Studio中的std :: initializer_list模糊性

做std :: initializer_list const会改变什么吗?

具有多种类型的std :: initializer_list

带有std :: initializer_list的奇怪行为constexpr

自动功能中带有std :: initializer_list <int>且不带const的==测试的C ++ 1z处理

为什么C ++使std :: initializer_list的元素类型为const?

当std :: initializer_list用作赋值参数时,为什么它不是引用类型?

为什么允许 std::initializer_list 不指定大小并同时分配堆栈?

std :: initializer_list <int>({1,2,3})和{1,2,3}有什么区别?

为什么 std::initializer_list 不支持 std::get<>、std::tuple_size 和 std::tuple_element

为什么 BigQuery 中的 case 语句没有按预期运行?

std :: initializer_list的实现

std :: initializer_list的实现

C ++ 11使用指针修改initializer_list中的元素导致了SIGSEGV,为什么?

为什么g ++ 5在自动类型推导中推导对象而不是initializer_list