[C++0x] Range-based for statements and ADL

Rodrigo Rivas rodrigorivascosta@gmail.com
Tue Mar 29 16:55:00 GMT 2011


On Tue, Mar 29, 2011 at 5:46 PM, Gabriel Dos Reis
<gdr@integrable-solutions.net> wrote:
> or "new-style for loop"?
Well, that is what they are called in Java, isn't it? And the syntax
is just the same, so it would make kind of sense.
But in the C++0x draft and the GCC docs it is almost always called
"range-based for loops, so I think it is preferred.


Talking of this... I tried the simplest wrong range-based for, with my
latest patch:

int main()
{
for (int x : 0)
    ;
}

And that is what I got:

test.cpp: In function ‘int main()’:
test.cpp:3:18: error: ‘begin’ was not declared in this scope
test.cpp:3:18: error: ‘end’ was not declared in this scope

That's ok. But now, if I add #include <vector> I get:

test.cpp: In function ‘int main()’:
test.cpp:4:18: error: no matching function for call to ‘begin(int&)’
test.cpp:4:18: note: candidates are:
/home/rodrigo/local/gcc/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/range_access.h:87:5:
note: template<class _Tp, unsigned int _Nm> _Tp* std::begin(_Tp
(&)[_Nm])
/home/rodrigo/local/gcc/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/range_access.h:58:63:
note: template<class _Container> decltype (__cont->begin())
std::begin(const _Container&)
/home/rodrigo/local/gcc/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/range_access.h:48:57:
note: template<class _Container> decltype (__cont->begin())
std::begin(_Container&)
/home/rodrigo/local/gcc/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/initializer_list:86:38:
note: template<class _Tp> constexpr const _Tp*
std::begin(std::initializer_list<_Tp>)
test.cpp:4:18: error: no matching function for call to ‘end(int&)’
test.cpp:4:18: note: candidates are:
/home/rodrigo/local/gcc/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/range_access.h:97:5:
note: template<class _Tp, unsigned int _Nm> _Tp* std::end(_Tp
(&)[_Nm])
/home/rodrigo/local/gcc/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/range_access.h:78:59:
note: template<class _Container> decltype (__cont->end())
std::end(const _Container&)
/home/rodrigo/local/gcc/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/range_access.h:68:53:
note: template<class _Container> decltype (__cont->end())
std::end(_Container&)
/home/rodrigo/local/gcc/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/initializer_list:96:36:
note: template<class _Tp> constexpr const _Tp*
std::end(std::initializer_list<_Tp>)

Although the error messages are technically correct, I find them too
verbose and probably misleading to the novice: "'begin' not declared?
I'm not using 'begin', I'm using 'for').
Note also that the error could be corrected adding member functions
begin/end (if the range were of class type), but that is not suggested
in the error message.

Maybe a simpler error is better. such as:
"expression is not valid as range in a range-based %<for%> loop
because it lacks begin/end members or begin(int&) and end(int&)
overloads." (I leave the wording to someone more skilled with
English).

Regards.
--
Rodrigo



More information about the Gcc-patches mailing list