2010-03-07 3 views
7

Возможно ли построить переменные аргументы для функции путем перегрузки операторской запятой аргумента? Я хочу посмотреть пример, как это сделать .., может быть, примерно так:C++ перегрузка операторской запятой для вариационных аргументов

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); 
+0

Почему вы должны сделать он использует запятую? Например. Boost.Assign уже дает вам четкий синтаксис, но использует 'operator()'. –

+0

, потому что я хочу, чтобы использование было так же просто, как MyFunction (1,2,3) not MyFunction (boost :: list_of (1) (2) (3)) – uray

ответ

11

Это sort- возможно, но использование не будет выглядеть очень красиво. Для 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)); 
} 

Этот недостаток будет исправлена ​​в C++ 0x, где вы можете сделать:

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}); 
} 

или даже со смешанными типами:

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"); 
} 
+0

это круто, его в TR1? – uray

+0

initializer_list? Я не уверен, так как для этого требуется встроенная поддержка языка. Но оба фрагмента, которые уже скомпилированы с GCC 4.4.1 с помощью std = C++ 0x – UncleBens

+0

, могут иметь глобальную статическую перегруженную операторскую запятую, например: 'template T & operator, (const T & a, T & b);'? – uray

1

Операторы имеют фиксированное количество параметров. Вы не можете это изменить. Оператор запятой принимает два аргумента. Так нет. Вы можете катить обычную каскадную версию, хотя и с некоторыми усилиями.

+0

Оператор запятой принимает один аргумент. – StilesCrisis

+0

@StilesCrisis Оператор запятой может принимать один или два аргумента. Используя два аргумента, вы указываете, что запятая может отображаться перед операндом и после другого типа. Это даже реже, чем обычная перегрузка одной запятой, которая уже довольно редка, но она существует. –

0

Нет, это не так. Список значений, разделенных оператором запятой, будет оцениваться как одно значение. Например:

1,2,3 

приведет к одному значению, 3.

+2

это то, что я хочу, функция все равно получает одно значение, но это значение было построено с помощью запятой оператора, я вижу, что можно было сделать объект MyObject = (1,2,3), я подумал, что можно изменить его на работать с MyObject как аргумент функции – uray

+0

@uray Извините, это совершенно неясно. Просьба изменить свой вопрос, чтобы проиллюстрировать, что вы хотите сделать. Например, каковы типы a, b, c и d в вашем примере кода? Помните, что вы не можете перегружать операторов для «встроенных» типов. – 2010-03-07 11:40:42

+0

@neil: я отредактировал мой вопрос – uray

1

Может быть что-то вроде этого:

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; 
}; 

Использование будет:

void foo(MyArgList& list); 
foo((myArgList(),1,2,3,4,5));