
I was looking for a convinient way to have variabele arguments for functions and avoiding the memory allocations and copying that come with std containers. I didn't find such a container so I hacked one together myself. The container builds a linked list by storing pointers to the arguments in temporary node objects (StackArg). The list becomes invalid as soon as the nodes go out of scope. A test showed that this was 5 times faster than using a std::vector. I don't have access to the code ATM, but look below how it looks like (very shortend). Ofcourse, the + operator is misleading (the leading empty StackArg<>() clarifies a lot) but otherwise it's pretty convinient. template<class T> class StackArg { public: StackArg *link; T *data; StackArg() link(0), data(0) {} StackArg(StackArg *prev, T *t) :link(prev), data(t) { } StackArg operator + (T &t) { return StackArg(this, &t); } iterator begin(); iterator end(); }; The first time when begin() or end() is called, the list is reversed because since operator+() is evaluated from left to right, the last element becomes the container handle (s in code below). // usage example: void print(StackArg<const int> s) // outputs 345 { StackArg<const int>::iterator i= s.begin(), e=end(); while(i!=e) cout << *i++; } void test() { print( StackArg<const int>() + 3 + 4 +5 ); }

"Eric Zijlstra" <ezijlstra@programmer.net> wrote in message news:d4un8k$tvr$1@sea.gmane.org... |I was looking for a convinient way to have variabele arguments for functions | and avoiding the memory allocations and copying that come with std | containers. I didn't find such a container so I hacked one together myself. | // usage example: | | void print(StackArg<const int> s) // outputs 345 | { | StackArg<const int>::iterator i= s.begin(), e=end(); | while(i!=e) cout << *i++; | } | | void test() | { | print( StackArg<const int>() + 3 + 4 +5 ); | } boost.assign features a new function that does just this: template< class Range > void print( const Range& s) // outputs 345 { typename Range::iterator i= s.begin(), e=end(); while(i!=e) cout << *i++; } void test() { print( boost::assign::cref_list_of<3>( 3 )( 4 )( 5 ) ); } there is also ref_list_of<N>() if you need to pass non-const references. The implementation uses an array of pointers and is as fast as possible IMO. -Thorsten

"Eric Zijlstra" <ezijlstra@programmer.net> wrote in message news:d4un8k$tvr$1@sea.gmane.org... |I was looking for a convinient way to have variabele arguments for functions | and avoiding the memory allocations and copying that come with std | containers. I didn't find such a container so I hacked one together myself. | The container builds a linked list by storing pointers to the arguments in | temporary node objects (StackArg). Just to let you know, I (*) tried this approach too and found it to be slower than using the array of pointers. (Thanks to Jens Theisen for showing me his ingeneous design that even could calculate the list size at compile-time!) -Thorsten
participants (2)
-
Eric Zijlstra
-
Thorsten Ottosen