c++c++14set-theory

n={0,1,...,n-1} in C++


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.


Solution

  • 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) and end(__range), respectively,

    Oo! This looks hopeful. You may need to move begin and end into the global namespace, but still...

    where begin and end 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))