ADL 不能在外面工作(即使是结构)

ADL not working outside (even of structure)

如果我有一个结构,重载 beginend 等,如下所示:

#include <array>

template<typename T>
struct Array10
{
private:
    std::array<T, 10> m_array;
public:
    constexpr auto begin()
    {
        return std::begin(m_array); // #1
    }

    constexpr auto end()
    {
        return std::end(m_array);
    }

    // cbegin, cend, rbegin, rend, crbegin, crend
};

int main()
{
    Array10<int> arr;
    std::fill(
    std::begin(arr), // #2
    std::end(arr),
    0);
}

然后我明白为什么我必须在#1 中使用 std::begin 而不是 begin(因为那是最接近的范围 begin 定义在其中),但我不明白为什么我必须在#2 中使用它。 我的第一个猜测是因为 Array10main 在同一个命名空间中,但将其放入自己的命名空间并没有解决问题。

那么:为什么 ADL 在 main(#2) 中找不到 std::begin

ADL 找不到成员。它会找到空闲函数。

您有一个成员foo.begin(),不是免费函数begin(foo)

friend constexpr auto begin(Array10&)
{
    return std::begin(m_array); // #1
}
friend constexpr auto begin(Array10 const&)
{
    return std::begin(m_array); // #1
}

这些是非成员 begin 函数,可通过 ADL 找到。