1

According to range based for loop documentation here:

begin_expr and end_expr are defined as follows:

  • If range_expression is an expression of array type, then begin_expr is __range and end_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 type C that has a member named begin and/or a member named end (regardless of the type or accessibility of such member), then begin_expr is __range.begin) and end_expr is __range.end();
  • Otherwise, begin_expr is begin(__range) and end_expr is end(__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.

Example

#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.

Demo

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?

2 Answers 2

2

[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 to U or an array of U, its associated namespaces and classes are those associated with U...

From these, a set of namespaces asscociated with char const* is empty, so there's nothing for ADL to look at.

Sign up to request clarification or add additional context in comments.

2 Comments

Hmm. Good to know.
Do you know if there was any motivation for that or is it just because that is how they defined it?
0

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".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.