为什么 ADL 不适用于未命名的initializer_list
Why does ADL not work with an unnamed initializer_list?
请考虑以下代码。在这里,如果我们在具有显式std::
的未命名initializer_list
上使用std::begin
,它可以正常工作。如果我们省略std::
并在命名initializer_list
上使用begin
,它也可以正常工作。但是,如果我们省略std::
并像第一种情况一样执行其余操作,则无法编译。
#include <iostream>
#include <iterator>
void func(int len, const int* x)
{
for(int i=0;i<len;++i)
std::cout << x[i] << "n";
}
int main()
{
{
// OK
func(5, std::begin({1,3,6,823,-35}));
}
{
// OK
auto&& list = {1,3,6,823,-35};
func(5, begin(list));
}
// {
// // Fails to compile
// func(5, begin({1,3,6,823,-35}));
// }
}
我收到以下编译错误(在我取消注释错误代码后(:
test.cpp: In function ‘int main()’:
test.cpp:21:11: error: ‘begin’ was not declared in this scope
func(5, begin({1,3,6,823,-35}));
^~~~~
test.cpp:21:11: note: suggested alternative:
In file included from /usr/include/c++/8/string:51,
from /usr/include/c++/8/bits/locale_classes.h:40,
from /usr/include/c++/8/bits/ios_base.h:41,
from /usr/include/c++/8/ios:42,
from /usr/include/c++/8/ostream:38,
from /usr/include/c++/8/iostream:39,
from test.cpp:1:
/usr/include/c++/8/bits/range_access.h:105:37: note: ‘std::begin’
template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);
^~~~~
为什么 ADL 适用于命名initializer_list
(即 list
在上面的例子中(,但失败了一个未命名的?
但是失败了一个未命名的?
不,{1,3,6,823,-35}
不是一个未命名的std::initializer_list
. {1,3,6,823,-35}
是一个带括号的初始化列表。即使它可以用来在指定的上下文中构造std::initializer_list
,但它本身并不std::initializer_list
。那么 ADL 将不适用于begin({1,3,6,823,-35})
.
大括号的初始化列表不是表达式,因此没有类型,例如
decltype({1,2})
格式不正确。
和
使用关键字
auto
进行类型推导有一个特殊的例外,它将任何带大括号的 init-list 推导出为std::initializer_list
。
这就是第二种情况起作用的原因; list
被贬为std::initializer_list&&
.
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- C++中带有List类的迭代器Segfault
- 使用"std::unordereded_map"映射到"std::list"对象
- GCC对可能有效的代码抛出init list生存期警告
- 使用std::list创建循环链表
- C2664 无法从'initializer list'转换参数
- 使用 std::min "no matching function for call to ‘min(<brace-enclosed initializer list>)’"时出错
- 在C++中标记化"Braced Initializer List"样式字符串(使用 Boost?
- "默认参数":无法从'initializer list'转换为'std::initializer_list'
- 无法从'initializer-list'转换为用户控制器
- 如何修复<function-style-cast>错误:无法从'initializer list'转换为asdending比较<W>(模板函子)
- 递归调用中出现错误"[Error] expression list treated as compound expression in initializer [-fpermissive]"
- VS2015无法从'initializer list'转换为'std::string'错误
- 编译器错误:"Non-aggregates cannot be initialized with initializer list."
- 无法转换...从 '<brace-enclosed initializer list>' 到 地图
- 无法将'<brace-enclosed initializer list>'转换为'double'作为回报
- <function-style-cast> 错误:无法从'initializer list'转换为'std::thread'
- initializer语言 - list不能转换为const margin *