The formal definition (in set theory) of a natural number n is as follows:
I think this would make some C++ code much simpler, if I was allowed to do this:
for (int n : 10)
cout << n << endl;
and it printed numbers from 0 to 9.
So I tried doing the following, which doesn't compile:
#include <iostream>
#include <boost/iterator/counting_iterator.hpp>
boost::counting_iterator<int> begin(int t)
{
return boost::counting_iterator<int>(0);
}
boost::counting_iterator<int> end(int t)
{
return boost::counting_iterator<int>(t);
}
int main()
{
for (int t : 10)
std::cout << t << std::endl;
return 0;
}
Any suggestions on how to achieve this? I get the following error with clang++:
main.cpp:22:20: error: invalid range expression of type 'int'; no viable 'begin' function available
for (int t : 10)
^ ~~
but I think I should be allowed to do this! :)
Edit: I know I can "fake" it if I add the word "range" (or some other word) in the for loop, but I'm wondering if it's possible to do it without.
It can't be done. From section 6.5.4 of the draft of the C++ 14 standard (but C++11 will be very similar)
begin-expr and end-expr are determined as follows:
(1.1) — if _
RangeT
is an array type, [...];
Well, this one obviously doesn't apply. An int
isn't an array
(1.2) — if _RangeT is a class type, [...]
Nope, this doesn't apply either.
(1.3) — otherwise, begin-expr and end-expr are
begin(__range)
andend(__range)
, respectively,
Oo! This looks hopeful. You may need to move begin
and end
into the global namespace, but still...
where
begin
andend
are looked up in the associated namespaces (3.4.2). [ Note: Ordinary unqualified lookup (3.4.1) is not performed. — end note ]
(emphasis mine). Bother! There aren't any namespaces associated with int
. Specifically, from section 3.4.2
— If T [
int
in our case] is a fundamental type, its associated sets of namespaces and classes are both empty.
The only workround is to write a class range
which has a suitable begin and end method. Then you could write the very pythonic:
for (int i : range(5))