ADL 不能在外面工作(即使是结构)
ADL not working outside (even of structure)
如果我有一个结构,重载 begin
、end
等,如下所示:
#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 中使用它。
我的第一个猜测是因为 Array10
与 main
在同一个命名空间中,但将其放入自己的命名空间并没有解决问题。
那么:为什么 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 找到。
如果我有一个结构,重载 begin
、end
等,如下所示:
#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 中使用它。
我的第一个猜测是因为 Array10
与 main
在同一个命名空间中,但将其放入自己的命名空间并没有解决问题。
那么:为什么 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 找到。