Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ overloading operator comma for variadic arguments

is it possible to construct variadic arguments for function by overloading operator comma of the argument? i want to see an example how to do so.., maybe something like this:

template <typename T> class ArgList {
public:
    ArgList(const T& a);
    ArgList<T>& operator,(const T& a,const T& b);
}
//declaration
void myFunction(ArgList<int> list);

//in use:
myFunction(1,2,3,4);

//or maybe:
myFunction(ArgList<int>(1),2,3,4);
like image 708
uray Avatar asked Mar 07 '10 11:03

uray


People also ask

Can we overload the comma operator?

In C++, we can overload the comma operator using Operator Overloading. For Example: For “Send the query X to the server Y and put the result in variable Z”, the “and” plays the role of the comma.

What is comma operator overloading in C++?

The purpose of comma operator is to string together several expressions. The value of a comma-separated list of expressions is the value of the right-most expression. Essentially, the comma's effect is to cause a sequence of operations to be performed. The values of the other expressions will be discarded.

What is the correct syntax to overload the operator?

When we overload the binary operator for user-defined types by using the code: obj3 = obj1 + obj2; The operator function is called using the obj1 object and obj2 is passed as an argument to the function.

Can we overload address of operator?

It is not possible to change the precedence, grouping, or number of operands of operators. The overload of operator -> must either return a raw pointer, or return an object (by reference or by value) for which operator -> is in turn overloaded.


3 Answers

It is sort-of possible, but the usage won't look very nice. For exxample:

#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>

template <class T>
class list_of
{
    std::vector<T> data;
public:
    typedef typename std::vector<T>::const_iterator const_iterator;
    const_iterator begin() const { return data.begin(); }
    const_iterator end() const { return data.end(); }

    list_of& operator, (const T& t) {
        data.push_back(t);
        return *this;
    }
};

void print(const list_of<int>& args)
{
    std::copy(args.begin(), args.end(), std::ostream_iterator<int>(std::cout, " "));
}

int main()
{
    print( (list_of<int>(), 1, 2, 3, 4, 5) );
}

This shortcoming will be fixed in C++0x where you can do:

void print(const std::initializer_list<int>& args)
{
    std::copy(args.begin(), args.end(), std::ostream_iterator<int>(std::cout, " "));
}

int main()
{
    print( {1, 2, 3, 4, 5} );
}

or even with mixed types:

template <class T>
void print(const T& t)
{
    std::cout << t;
}

template <class Arg1, class ...ArgN>
void print(const Arg1& a1, const ArgN& ...an)
{
    std::cout << a1 << ' ';
    print(an...);
}


int main()
{
    print( 1, 2.4, 'u', "hello world" );
}
like image 95
UncleBens Avatar answered Sep 23 '22 19:09

UncleBens


Operators have a fixed number of parameters. You cannot change that. The comma operator takes two arguments. So no. You can roll a custom, cascading version though, with some effort.

like image 36
dirkgently Avatar answered Sep 22 '22 19:09

dirkgently


Maybe something like this:

class MyArgList {
public:   
     typedef std::list<boost::any> ManyList;

     template <typename T>
     MyArgList& operator, (const T& val) {
        elems.push_back(val);
        return *this; 
     }

     ManyList::iterator begin() {return elems.begin();}
       ...

private:
     ManyList elems;
};

Usage would be:

void foo(MyArgList& list);
foo((myArgList(),1,2,3,4,5));
like image 24
Alexander Gessler Avatar answered Sep 26 '22 19:09

Alexander Gessler