c++ - 为什么 ADL 不适用于未命名的 initializer_list?
问题描述
考虑以下代码。在这里,如果我们std::begin
在未命名initializer_list
的 with explicit上使用std::
,它可以正常工作。如果我们在 named 上省略std::
and 使用,它也可以正常工作。但是如果我们省略并像第一种情况那样做其余的事情,它就无法编译。begin
initializer_list
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
,它将任何花括号初始化列表推导为std::initializer_list
。
这就是第二种情况有效的原因;list
推断为std::initializer_list&&
。
推荐阅读
- angular - 除单个组件外的所有组件都使用哈希
- shopify - 如何通过仅采用产品名称字段的表单在 Shopify 的购物车中添加产品?
- c++ - C++ 在容器上使用多个过滤器,开销更少
- android - 单击列表视图项后的图像滑块
- android - 在我的应用程序中实施/集成谷歌语音操作/谷歌助手
- java - 如何在按下按钮时弹跳或缩放动画
- mysql - 如何通过增加批量更新中的值来更新字段
- sql-server - 案例语句中的硬代码日期比较
- android - 是否已备份本机 iOS / Android 密钥存储并且可以转移它们?
- c# - Foreach 循环仅遵循 C# 中 SQL Server 中的第一行数据表进行指纹验证