7

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);
Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
uray
  • 11,254
  • 13
  • 54
  • 74
  • Why do you need to do it using the comma operator? E.g. Boost.Assign already gives you a neat syntax, but it uses `operator()`. – Georg Fritzsche Mar 07 '10 at 12:17
  • because i want the usage as simple as MyFunction(1,2,3) not MyFunction(boost::list_of(1)(2)(3)) – uray Mar 07 '10 at 12:28

4 Answers4

11

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" );
}
UncleBens
  • 40,819
  • 6
  • 57
  • 90
  • initializer_list? I'm not sure since it needs built-in support from the language to work. But both snippets already compile with GCC 4.4.1 with std=C++0x – UncleBens Mar 07 '10 at 11:52
  • can we have global static overloaded operator comma like : `template T& operator, (const T& a, T& b);` ? – uray Mar 07 '10 at 11:56
  • As Neil already mentioned, not for *"built-in"* types, so you have to start the expressions with something like `list_of()`. – Georg Fritzsche Mar 07 '10 at 12:35
  • Another thing that would eliminate the need for extra parenthesis would be to use some other operator: `print(list_of() % 1 % 2 % 3);` You could also use template type deduction, if the first item was given to a function returning a `list_of`: `print(make_list_of(1) % 2 % 3);` But it is ugly in every way. If it was possible to simulate it nicely, C++0x wouldn't add the changes to the language. – UncleBens Mar 08 '10 at 15:37
1

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.

dirkgently
  • 108,024
  • 16
  • 131
  • 187
  • The comma operator takes one argument. – StilesCrisis Jan 18 '13 at 00:22
  • @StilesCrisis The comma operator can actually take one or two args. Using two args, you specify that the comma can appear before the operand and after another type. It's even less common than regular one-arg comma overloading, which is already pretty rare, but it exists. – Darrel Hoffman Jun 30 '13 at 02:14
1

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));
Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
0

No, it isn't. The list of values separated by the comma operator will be evaluated as a single value. For example:

1,2,3

will result in a single value, 3.

  • 2
    that's what i want, the function still receive single value, but that value was constructed by operator comma, i see that it was possible to do MyObject object = (1,2,3), i thought it was possible to modify it to be working with MyObject as function argument – uray Mar 07 '10 at 11:31
  • @uray Sorry, that is completely unclear. Pleas modify your question to illustrate what you want to do. For example, what are the types of a,b,c and d in your example code? Remember, you cannot overload operators for the "built-in" types. –  Mar 07 '10 at 11:40
  • @uray, the problem is you gotta put parenthesis around your arguments list, because the compiler will otherwise complain about an exceeding amount of arguments to the function, that is it will not understand those are *not* multiple arguments. – Fabio A. Mar 26 '12 at 20:41