c++ - 为什么 ADL 不能使用未命名的 initializer_list?

标签 c++ c++11 initializer-list argument-dependent-lookup

考虑以下代码。在这里,如果我们在未命名的 initializer_list 上使用 std::begin 并显式使用 std::,它就可以正常工作。如果我们省略 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)但使用未命名的列表失败?

最佳答案

but fail with an unnamed one?

不,{1,3,6,823,-35} 不是未命名的 std::initializer_list{1,3,6,823,-35}braced-init-list .它甚至可以用于在指定的上下文中构造一个 std::initializer_list 但它不是 std::initializer_list 本身。那么 ADL 将不适用于 begin({1,3,6,823,-35})

A braced-init-list is not an expression and therefore has no type, e.g. decltype({1,2}) is ill-formed.

A special exception is made for type deduction using the keyword auto , which deduces any braced-init-list as std::initializer_list.

这就是第二种情况有效的原因; list 被推断为 std::initializer_list&&

关于c++ - 为什么 ADL 不能使用未命名的 initializer_list?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56701480/

相关文章:

c++ - 从文件读取/写入时双重释放或损坏

c++ - strcpy_s 复制超过字符串长度到目标缓冲区(用 0xFE 填充)

postgresql - Postgis + boost::geometry + C++

c++ - Lambda 函数作为基类

c++ - 通过 make_unique/make_shared 调用 initializer_list 构造函数

c++ - 为什么 C++ 允许将 std::initializer_list 强制转换为基本类型,并用于初始化它们?

c++ - 引用如何/在哪里存储在 C++ 中?

c++ - 如何在 Spirit x3 中执行 no_case

C++ 入门第五练习 7.52

c++ - 为什么嵌套的initializer_list会导致内存泄漏