为什么 free 函数不能在 C 数组上运行,而 std::begin 在某些情况下可以在 C++14 中运行?

Why can't the free function begin operate on C arrays while std::begin can in C++14 in some cases?

本文关键字:运行 begin 情况下 C++14 不能 函数 free 数组 为什么 std      更新时间:2023-10-16

我注意到在某些情况下开始(没有名称空间规范的没有名称空间(,而在其他情况下会失败。

你们能解释一下为什么它在工作时能起作用,为什么由于用例而有差异?

根据VS2017 15.9.7和GCC-8.3.0,代码无法以相同的方式编译。STD = C 14均用于两者。vs:错误C3861:'begin':找不到标识符GCC:错误:在此范围中未声明"开始"

#include <array>
struct Struct {
    int x;
};
int main()
{
    {
        std::array<int, 4> arr;
        std::begin(arr);
        begin(arr);     // works, calls the same as std::begin above
    }
    {
        std::pair<int, int> arr[4];
        std::begin(arr);
        begin(arr);     // works, calls the same as std::begin above
    }
    {
        int arr[4];
        std::begin(arr);
        begin(arr);     // error
    }
    {
        Struct arr[4];
        std::begin(arr);
        begin(arr);     // error
    }
}

我期望没有STD ::的开始,因为它在STD名称空间中声明,没有人说使用名称空间STD或使用开始。(或者如果有人这样做,就不会出错(

我在标记为"工作"的前两行中调试,我看到它跳入了同一std ::开始像一行一样开始实现。

标记"works"的语句工作,因为传递给begin的参数属于与begin相同的名称空间。

在下面的示例中:

std::array<int, 4> arr;
begin(arr);     // works, calls the same as std::begin above

参数arr的类型属于命名空间std::begin也属于命名空间std

要查找begin编译器不仅要查看本地范围,还要查看包含参数类型的名称空间。这称为参数依赖性查找。当编译器查看std名称空间时,它找到了begin并能够称呼它。

当参数的类型为 std::pair

时,情况是相同的

但是,在标记为"错误"的语句中,传递给begin的参数的类型是C风格数组和Struct。这两个都不属于std名称空间。因此,编译器找不到begin,因此无法调用。