Reputation: 10911
According to range based for loop documentation here:
begin_expr
andend_expr
are defined as follows:
- If range_expression is an expression of array type, then
begin_expr
is__range
andend_expr
is(__range + __bound)
, where__bound
is the number of elements in the array (if the array has unknown size or is of an incomplete type, the program is ill-formed)- If
range_expression
is an expression of a class typeC
that has a member namedbegin
and/or a member namedend
(regardless of the type or accessibility of such member), thenbegin_expr
is__range.begin
) andend_expr
is__range.end()
;- Otherwise,
begin_expr
isbegin(__range)
andend_expr
isend(__range)
, which are found via argument-dependent lookup (non-ADL lookup is not performed).
However, if I define begin()
and end()
for a pointer type, it fails to work.
#include <iostream>
using LPCSTR = char const*;
LPCSTR begin(LPCSTR str)
{
return str;
}
LPCSTR end(LPCSTR str)
{
return str + strlen(str);
}
int main()
{
LPCSTR text = "Hello, world!\n";
for (auto c : text)
{
std::cout << c;
}
}
Error(s):
source_file.cpp:18:17: error: invalid range expression of type 'const char *'; no viable 'begin' function available
for (auto c : text)
^ ~~~~
1 error generated.
I don't see any reference that pointers are excluded from the ADL, so what reason would there be as to why this isn't working?
Upvotes: 1
Views: 1394
Reputation: 52471
[basic.lookup.argdep]/2 For each argument type
T
in the function call, there is a set of zero or more associated namespaces and a set of zero or more associated classes to be considered...(2.1) — If
T
is a fundamental type, its associated sets of namespaces and classes are both empty...(2.4) — If
T
is a pointer toU
or an array ofU
, its associated namespaces and classes are those associated withU
...
From these, a set of namespaces asscociated with char const*
is empty, so there's nothing for ADL to look at.
Upvotes: 2
Reputation: 7904
The issue is this part:
non-ADL lookup is not performed
begin
and end
in this context would be found by non-ADL lookup, rather than ADL since pointers aren't "defined in the global namespace".
Upvotes: 0