3
#include <iostream>
#include <vector>

using namespace std;

//
// Below is what I want but not legal in current C++!
//
vector<int> operator ...(int first, int last)
{
    vector<int> coll;
    for (int i = first; i <= last; ++i)
    {
        coll.push_back(i);
    }

    return coll;
}

int main()
{
    for (auto i : 1...4)
    {
        cout << i << endl;
    }
}

I want to generate an integer sequence by using syntax 1...100, 7...13, 2...200 and the like.

I want to overload ... in C++.

Is it possible?

xmllmx
  • 39,765
  • 26
  • 162
  • 323

3 Answers3

4

Is it possible?

No, it isn't possible.

... isn't an operator but a placeholder for variadic arguments.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
3

There is no ... operator in C++, so you can't overload it.

However, you can use an ordinary name such as range.

Assuming a header that defines a suitable range function, your intended program

int main()
{
    for (auto i : 1...4)
    {
        cout << i << endl;
    }
}

… can then look like this:

#include <p/expressive/library_extension.hpp>
using progrock::expressive::range;

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    for( auto i : range( 1, 4 ) )
    {
        cout << i << endl;
    }
}

This is actual working code using the Expressive C++ library's range implementation. However, that library is currently in its very infant stages, in flux, with all kinds of imperfections and fundamental changes daily. Also it implements an extended dialect of C++, that is as yet unfamiliar to all but myself, so that posting the range implementation here where pure C++ is expected, would possibly/probably provoke negative reactions; I'm sorry. But you can easily translate that implementation to raw C++. It's Boost 1.0 license.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
1

As mentioned in the other answers this is not possible since ... is not a valid operator, but in this language you can always create weird idioms like this:

#include <iostream>

struct int_it
{
    int_it (int l, int r): left(l), right(r){}

    void operator++() { left++;}
    bool operator!=(const int_it& rhs) { return left != rhs.right;}
    int operator*(){ return left;};

    int left;
    int right;
};

class range_op
{
public:
    static range_op op() { return {0,0}; } 
    operator int() { return right - left; }
    auto begin(){ return int_it{left, right}; }
    auto end(){ return int_it{right,right}; }
private:
    range_op(int l, int r): left(l), right(r){}
    int left;
    int right;

    friend range_op operator*(int lhs, range_op r);
    friend range_op operator*(range_op r, int rhs);
};

range_op operator*(int lhs, range_op r)
{
   return range_op{lhs, r.right};
}

range_op operator*(range_op d, int rhs)
{
    return range_op{d.left, rhs};
}

const auto o = range_op::op();

int main() {    
    for (int i : 2*o*6)
    {
        std::cout << i << std::endl;
    }
    return 0;
}

This is just a quick example, so no range checks and a lot of bugs.

dlavila
  • 1,204
  • 11
  • 25