Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > vector assign

Reply
Thread Tools

vector assign

 
 
stephen b
Guest
Posts: n/a
 
      05-23-2008
Hi all, personally I'd love to be able to do something like this:

vector<int> v;
v.assign(1, 2, 5, 9, 8, 7) etc

without having to manually add elements by doing v[0] = 1, v[1] = 2 ..
etc.

it would make for much more readable code that is faster to write in
some situations. I've not seen this feature documented anywhere
though which I find curious. is there another way to achieve this?

thanks,
stephen.


 
Reply With Quote
 
 
 
 
Darío Griffo
Guest
Posts: n/a
 
      05-23-2008
stephen b wrote:
> it would make for much more readable code that is faster to write in
> some situations. I've not seen this feature documented anywhere
> though which I find curious. is there another way to achieve this?


Maybe using variable arguments and inheritance

#include <iostream>
#include <vector>
#include <stdarg.h>
#include <iterator>

template <typename T > class myVec: public std::vector<T>
{
public:
void assign(int amount,...);
};

template <typename T > void myVec<T>::assign(int amount,...)
{
T val;
va_list vl;
va_start(vl,amount);
for (int i=0;i<amount;i++)
{
val=va_arg(vl,T);
push_back(val);
}
va_end(vl);
}

int main()
{

myVec<int> vec;
vec.assign(3,2,1,0);
std::copy(vec.begin(),vec.end(),std:stream_itera tor<int>(std::cout,
" "));
return 0;
}

Darío
 
Reply With Quote
 
 
 
 
acehreli@gmail.com
Guest
Posts: n/a
 
      05-23-2008
On May 23, 3:40 pm, stephen b <(E-Mail Removed)> wrote:
> Hi all, personally I'd love to be able to do something like this:
>
> vector<int> v;
> v.assign(1, 2, 5, 9, 8, 7) etc


Checkout Boost's Assign Library. You can do these:

vector<int> v;
v += 1,2,3,4,5,6,7,8,9;

or

vector<int> v = list_of(1)(2)(3);

etc.

Ali

 
Reply With Quote
 
stephen b
Guest
Posts: n/a
 
      05-24-2008
On May 23, 5:48*pm, (E-Mail Removed) wrote:
> On May 23, 3:40 pm, stephen b <(E-Mail Removed)> wrote:
>
> > Hi all, personally I'd love to be able to do something like this:

>
> > vector<int> v;
> > v.assign(1, 2, 5, 9, 8, 7) etc

>
> Checkout Boost's Assign Library. You can do these:
>
> vector<int> v;
> v += 1,2,3,4,5,6,7,8,9;
>
> or
>
> vector<int> v = list_of(1)(2)(3);


Thanks, that looks really promising, I'll check it out. Stephen.
 
Reply With Quote
 
Darío Griffo
Guest
Posts: n/a
 
      05-24-2008


Daniel T. wrote:
> Would this work for non-POD types?

A simple test told me not

compiling test.cpp (g++)
test.cpp:65: instantiated from here
test.cpp:56: warning: cannot receive objects of non-POD type 'class A'
through '...'; call will abort at runtime


BTW inheritance is not necessary.

I know, but since we program in OOP paradigm, it seems to me the best
way to do that.

>
> template < typename T >
> void assign( std::vector<T>& vec, int count, ... )
> {
> va_list vl;
> va_start( vl, count );
> for ( int i=0; i!= count; ++i)
> {
> vec.push_back( va_arg( vl, T ) );
> }
> va_end(vl);
> }
>
> using namespace std;
>
> int main()
> {
> vector<int> vec;
> assign( vec, 3, 2, 1, 0 );
> copy( vec.begin(), vec.end(), ostream_iterator<int>( cout, " " ) );
> }
>
> }

 
Reply With Quote
 
Jerry Coffin
Guest
Posts: n/a
 
      05-24-2008
In article <54590b15-eafb-45ca-83ac-3768a65f8e65@
2g2000hsn.googlegroups.com>, http://www.velocityreviews.com/forums/(E-Mail Removed) says...
> Hi all, personally I'd love to be able to do something like this:
>
> vector<int> v;
> v.assign(1, 2, 5, 9, 8, 7) etc
>
> without having to manually add elements by doing v[0] = 1, v[1] = 2 ..
> etc.
>
> it would make for much more readable code that is faster to write in
> some situations. I've not seen this feature documented anywhere
> though which I find curious. is there another way to achieve this?


If you have a predefined set of elements (and that's all the vector will
need to hold) you might want to look into using TR1::array instead of a
vector (the same class is in the current draft for C++ 0x as std::array
as well).

If you will/might need to expand the collection later, you'll still need
to use a vector, but you can initialize the array from the constants,
and then initialize the vector from the array:

TR1::array<int> a = {1, 2, 5, 9, 8, 7};

std::vector<int>v(a.begin(), a.end());

That may not be perfect, but it's still pretty decent.

There have been a number of other methods invented, but none of them is
particularly clean. I once wrote a bit of code to deal with this
problem, but it's sufficiently ugly that I never use it myself, so I'd
have some difficulty recommending that anybody else do so either:

template<class T>
class fill_vector {
std::vector<T> data;
public:
fill_vector(T const &val) {
data.push_back(val);
}

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

operator std::vector<T>() { return data; }
};

template<class T>
fill_vector<T> fillVect(T const &t) {
return fill_vector<T>(t);
}

std::vector<int> iv = (fillVect(1), 2, 5, 9, 8, 7);

I wouldn't mind if the code for fill_vector or fill_vect was ugly, but
the code to use them needs those seemingly extraneous parentheses, so
the code that uses this technique is unavoidably rather ugly. That
really _does_ bother me.

Another direction is to start with an array, and just have a reasonably
clean way of supplying iterators to the beginning and end of the array
so you can initialize the vector from it cleanly:

template <class T, size_t N>
T *end(T (&input)[N]) {
return input+N;
}

int init[] = { 1, 2, 5, 9, 8, 7};

std::vector<int> v(init, end(init));

Like the version that initializes a vector from a TR1::array, this
separates creation of the vector from defining its initial data, and
requires a name for the object holding that initial data. That's not
really ideal, but in practice I've never really run into a major problem
with it either.

Choosing between TR1::array and/or std::array and this last version,
isn't necessarily simple. If you already have the array class available
(on all compilers you need to target), you might as well use it. If you
don't have it available, you need to decide whether the number of times
you could use an array object directly (rather than just to initialize a
vector) justifies finding and installing an implementation. That'll
depend on circumstances about which I know too little to comment
intelligently.

--
Later,
Jerry.

The universe is a figment of its own imagination.
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-24-2008
On May 24, 1:48 am, (E-Mail Removed) wrote:
> On May 23, 3:40 pm, stephen b <(E-Mail Removed)> wrote:


> > Hi all, personally I'd love to be able to do something like this:


> > vector<int> v;
> > v.assign(1, 2, 5, 9, 8, 7) etc


> Checkout Boost's Assign Library. You can do these:


> vector<int> v;
> v += 1,2,3,4,5,6,7,8,9;


Institutionalized obfuscation, anyone? That statement has a
predefined meaning in C++, without any library, and any code
which changes a predefined meaning should be avoided at all
costs.

> or


> vector<int> v = list_of(1)(2)(3);


That's better. A lot of the time, of course, simply:

static int const init[] = { 1, 2, 5, 9, 8, 7 } ;
std::vector< int > v( begin( init ), end( init ) ) ;

is just as good.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-24-2008
On May 24, 8:01 am, Jerry Coffin <(E-Mail Removed)> wrote:
> In article <54590b15-eafb-45ca-83ac-3768a65f8e65@
> 2g2000hsn.googlegroups.com>, (E-Mail Removed) says...


> If you will/might need to expand the collection later, you'll
> still need to use a vector, but you can initialize the array
> from the constants, and then initialize the vector from the
> array:


> TR1::array<int> a = {1, 2, 5, 9, 8, 7};


Can TR1::array deduce the length from the number of elements in
the initialization list? (And if so, how?)

IIUC, the standard is extending initialization syntax
expressedly to deal with such cases (and will allow an
initialization list directly in the definition of the vector),
but I didn't think that it could be done today.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Frank Birbacher
Guest
Posts: n/a
 
      05-24-2008
Hi!

DarÃ*o Griffo schrieb:
>> BTW inheritance is not necessary.

>
> I know, but since we program in OOP paradigm, it seems to me the best
> way to do that.


No. It is not the best way although we have "OOP" at our disposal (I
think of "OOP" here as "derive from a base class"). A vector makes no
good base class. You must not derive from it. Value based classes are
usually not suited for inheritance. Think of a "long" derived from an
"int"!?

A better way to do it is to write a complete wrapper and add
functionality as needed:

template<typename T>
class AssignableVector
{
vector<T> data;
public:
AssignableVector() {}
AssignableVector(size_t n, T const t = T())
: data(n, t)
{}
//forward all functions to the vector:
void push_back(T const t) { data.push_back(t); }
...

//add extra functionality:
void assign(/*whatever parameters are needed*/) { ... }
};

This it much code. And it is boring to write. I guess that's why many
people resort to inheritance: just to save typing.

When I can't really convince you not to use inheritance, then at least
use private inheritance to hide it. (Which means you would have to
somehow provide public versions of the inherited methods, which needs
the same typing than above after all).

Regards,
Frank
 
Reply With Quote
 
Frank Birbacher
Guest
Posts: n/a
 
      05-24-2008
Hi!

Alf P. Steinbach schrieb:
> I don't think it's worth it or even a good idea to add more features,
> but it's easy to do that also, e.g.
>
> struct Clear {};
>
> template< typename T >
> std:vector<T>& operator <<( std::vector<T>& v, Clear )
> {
> std::vector<T>().swap( v );
> return v;
> }
>
> enabling things like
>
> v << Clear() << 1 << 2 << 3;


Right, no a good idea, in my opinion.

v1 << 1 << 2 << Swap(v2 << Clear() << 3 << 3) << v3 << Print(std::cout);

o_O

Frank
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Initializing vector<vector<int> > and other vector questions... pmatos C++ 6 04-26-2007 05:39 PM
Vector Assign vs Vector operator= Chris Roth C++ 4 02-22-2007 12:57 PM
Free memory allocate by a STL vector, vector of vector, map of vector Allerdyce.John@gmail.com C++ 8 02-18-2006 12:48 AM
how the vector is created, how to pass vector to webservices method apachesoap:Vector Rushikesh Joshi Perl Misc 0 07-10-2004 01:04 PM



Advertisments