tjw*_*992 6 c++ initializer-list auto type-deduction
我正在尝试使用auto自动推断嵌套的类型std::initializer_list。
auto list = {
{{ 0, 1}, { 2, 3 }},
{{ 4, 5}, { 6, 7 }},
};
Run Code Online (Sandbox Code Playgroud)
这里的实际类型是std::initializer_list<std::initializer_list<std::initializer_list<int>>>,但是当我尝试编译它时,我收到一条错误,指出auto无法推断出该类型。有什么方法可以auto识别这样的构造吗?
我有一个程序,其中这些初始值设定项列表可以具有任意大小和深度,因此对类型进行硬编码是不切实际的。
我在这里找到了有关初始化程序列表的文档:https ://en.cppreference.com/w/cpp/language/list_initialization
花括号初始化列表不是表达式,因此没有类型,例如格式
decltype({1,2})错误。没有类型意味着模板类型推导无法推导出与花括号初始化列表匹配的类型,因此给定声明的template<class T> void f(T);表达式格式f({1,2,3})不正确。但是,可以以其他方式推导模板参数,就像 的情况一样std::vector<int> v(std::istream_iterator<int>(std::cin), {}),其中迭代器类型由第一个参数推导,但也用于第二个参数位置。使用关键字 auto 进行类型推导有一个特殊的例外,它会像std::initializer_list复制列表初始化一样推导任何花括号初始化列表。
该文档似乎表明,对于类型推导使用有一个特殊的例外,auto因此您会认为这会起作用......但似乎当您使用嵌套列表时auto无法推导类型。
我有一个程序,其中这些初始值设定项列表可以具有任意大小和深度,因此对类型进行硬编码是不切实际的。
那么你需要解决这个问题。
您不应该将花括号初始化列表视为一种创建值数组的快速而肮脏的方法,而不必考虑它们的类型。那不是他们的目的。它们的目的是初始化值。该类型std::initializer_list旨在成为初始化某些类型的过程中的中间阶段(这就是为什么采用 single 的构造函数initializer_list在列表初始化中被赋予特殊含义)。
如果您想要拥有各种深度的数组的数组等,那么您将需要弄清楚该构造需要是哪种类型并将其键入。auto只能推导出单个级别的braced-init-list;如果需要更深层次,则需要显式指定类型。
对于类型推导有一个特殊的例外:
auto
就在这里。但它仅适用于推导列表本身auto ,不适用于auto推导所需的任何内容。
为了auto list = {{1, 2, 3}};工作,编译器必须推断出两种类型:要使用的类型{1, 2, 3}和要使用的类型list。类型的推导list需要推导嵌套的花括号初始化列表的类型。但您无法推断出花括号初始化列表的类型。因此它不起作用。
还应该指出的是,即使它确实有效,它实际上也不会起作用。原因是 的initializer_list内部list会引用一个临时数组。一个临时数组,将在初始化表达式结束时销毁。string_view sv = std::string("foo");这基本上与没有产生有用的东西的原因相同。
| 归档时间: |
|
| 查看次数: |
1459 次 |
| 最近记录: |