By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,537 Members | 1,750 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,537 IT Pros & Developers. It's quick & easy.

vector assign

P: n/a
Hi all, personally I'd love to be able to do something like this:

vector<intv;
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.
Jun 27 '08 #1
Share this Question
Share on Google+
29 Replies


P: n/a
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<intvec;
vec.assign(3,2,1,0);
std::copy(vec.begin(),vec.end(),std::ostream_itera tor<int>(std::cout,
" "));
return 0;
}

Darío
Jun 27 '08 #2

P: n/a
In article
<25**********************************@k37g2000hsf. googlegroups.com>,
Darío Griffo <da*****************@gmail.comwrote:
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<intvec;
vec.assign(3,2,1,0);
std::copy(vec.begin(),vec.end(),std::ostream_itera tor<int>(std::cout,
" "));
return 0;
}

Darío
Would this work for non-POD types? BTW inheritance is not necessary.

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<intvec;
assign( vec, 3, 2, 1, 0 );
copy( vec.begin(), vec.end(), ostream_iterator<int>( cout, " " ) );
}

}
Jun 27 '08 #3

P: n/a
On May 23, 3:40 pm, stephen b <ker...@audiospillage.comwrote:
Hi all, personally I'd love to be able to do something like this:

vector<intv;
v.assign(1, 2, 5, 9, 8, 7) etc
Checkout Boost's Assign Library. You can do these:

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

or

vector<intv = list_of(1)(2)(3);

etc.

Ali

Jun 27 '08 #4

P: n/a
On May 23, 5:48*pm, acehr...@gmail.com wrote:
On May 23, 3:40 pm, stephen b <ker...@audiospillage.comwrote:
Hi all, personally I'd love to be able to do something like this:
vector<intv;
v.assign(1, 2, 5, 9, 8, 7) etc

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

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

or

vector<intv = list_of(1)(2)(3);
Thanks, that looks really promising, I'll check it out. Stephen.
Jun 27 '08 #5

P: n/a


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<intvec;
assign( vec, 3, 2, 1, 0 );
copy( vec.begin(), vec.end(), ostream_iterator<int>( cout, " " ) );
}

}
Jun 27 '08 #6

P: n/a
In article <54590b15-eafb-45ca-83ac-3768a65f8e65@
2g2000hsn.googlegroups.com>, ke****@audiospillage.com says...
Hi all, personally I'd love to be able to do something like this:

vector<intv;
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<inta = {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<Tdata;
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<TfillVect(T const &t) {
return fill_vector<T>(t);
}

std::vector<intiv = (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<intv(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.
Jun 27 '08 #7

P: n/a
On May 24, 1:48 am, acehr...@gmail.com wrote:
On May 23, 3:40 pm, stephen b <ker...@audiospillage.comwrote:
Hi all, personally I'd love to be able to do something like this:
vector<intv;
v.assign(1, 2, 5, 9, 8, 7) etc
Checkout Boost's Assign Library. You can do these:
vector<intv;
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<intv = 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:ja*********@gmail.com
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
Jun 27 '08 #8

P: n/a
On May 24, 8:01 am, Jerry Coffin <jcof...@taeus.comwrote:
In article <54590b15-eafb-45ca-83ac-3768a65f8e65@
2g2000hsn.googlegroups.com>, ker...@audiospillage.com 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<inta = {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:ja*********@gmail.com
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
Jun 27 '08 #9

P: n/a
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<Tdata;
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
Jun 27 '08 #10

P: n/a
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
Jun 27 '08 #11

P: n/a
Hi!

Alf P. Steinbach schrieb:
>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.

Good, yet possibly bad. Good for vector. Bad if it isn't more general.
Meaning from an expression explicitly constructing an object, the final
type can be deduced from the arguments passed to the constructor? like:

array<int>({4,5,6}) //deduce size n from use of ctor array(T[n])??

or:

ostream_iterator<int>(std::wcout) //deduce wchar_t usage

?

Frank
Jun 27 '08 #12

P: n/a
On 2008-05-24 05:04:08 -0400, James Kanze <ja*********@gmail.comsaid:
On May 24, 8:01 am, Jerry Coffin <jcof...@taeus.comwrote:
>In article <54590b15-eafb-45ca-83ac-3768a65f8e65@
2g2000hsn.googlegroups.com>, ker...@audiospillage.com 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<inta = {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?)
No, you have to supply the length.

tr1::array<int, 7a = {1, 2, 5, 9, 8, 7}; // last element is 0...
>
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.
Instantiations of tr1::array (and std::array in C++0x) are PODS, so can
be initialized with that syntax. That was one of the goals in its
design.

In addition, as you say, for C++0x there's a proposal working its way
through the process to support that sort of initialization for non-POD
types. I'm not familiar with the details,

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jun 27 '08 #13

P: n/a
Frank Birbacher wrote:
Darío Griffo schrieb:
Daniel T. wrote:
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"!?
I guess you would have a real problem with the following then? :-)

template<class Tclass Vec : public vector<T{
public:
Vec() : vector<T>() { }
Vec(int s) : vector<T>(s) { }

T& operator[](int i) { return at(i); }
const T& operator[](int i) const { return at(i); }
}; //(1)

Seriously though, I do agree with you. Despite the citation of the above
source, I too think that such derivation is generally inappropriate.
Especially in this case because the assign(...) function would be useful
on several different containers, not just vectors so why limit its use
artificially?

That said, I see now that the functionality that the OP requested is
already in the vector class (as pointed out by James Kanze.)

(1) Stroustrup, Bjarne. "The C++ Programming Language (3rd ed.) 1997
Jun 27 '08 #14

P: n/a
Hi!

Daniel T. schrieb:
I guess you would have a real problem with the following then? :-)

template<class Tclass Vec : public vector<T{
Yes. It doesn't work polymorphically, you know. And you agree.

void foo(vector<Tconst& data)
{
data[3]; //should throw, but doesn't ??

Regards,
Frank
Jun 27 '08 #15

P: n/a
In article <5a4cc544-b89a-4c82-8b1f-
7a**********@l64g2000hse.googlegroups.com>, ja*********@gmail.com
says...
On May 24, 8:01 am, Jerry Coffin <jcof...@taeus.comwrote:
[ ... ]
TR1::array<inta = {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?)
Oops -- sorry, but no. You have to supply the size as a template
parameter. My apologies for the typo.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 27 '08 #16

P: n/a
On May 24, 12:34 pm, "Alf P. Steinbach" <al...@start.nowrote:
* James Kanze:
On May 24, 1:48 am, acehr...@gmail.com wrote:
On May 23, 3:40 pm, stephen b <ker...@audiospillage.comwrote:
>Hi all, personally I'd love to be able to do something like this:
>vector<intv;
v.assign(1, 2, 5, 9, 8, 7) etc
Checkout Boost's Assign Library. You can do these:
vector<intv;
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.
I tend to use "<<" for adding things to some logical
container.
There are arguments both ways. According to some, the
"abstraction" of << is formatting. At least one specialist even
argued that it was formatting text. Others consider it simply
"insertion". If you are of the latter school, it's the obvious
solution.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #17

P: n/a
On May 24, 12:45 pm, "Alf P. Steinbach" <al...@start.nowrote:
* James Kanze:
On May 24, 8:01 am, Jerry Coffin <jcof...@taeus.comwrote:
In article <54590b15-eafb-45ca-83ac-3768a65f8e65@
2g2000hsn.googlegroups.com>, ker...@audiospillage.com 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<inta = {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?)
No, it's just ordinary POD initialization (no constructors in
that class).
That was my believe as well, but every time I think something
can't be done, someone comes up with some metaprogramming trick
to do it.
So above seems to be a typo, missing size parameter.
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.
Good, yet possibly bad. Good for vector. Bad if it isn't
more general.
It will definitely be more general. I've not really looked at
it myself, so I don't know the details, but I think the idea is
that it will work for any type which has a two iterator
constructor.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #18

P: n/a
Checkout Boost's Assign Library. You can do these:
vector<intv;
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.
I can't find a definition anwyhere of what the += operator does with
vectors. I'd be happy if, say, v += 2 iterated over the vector and
added the value 2 to each element. similarly if v *= 5 multiplied all
elements then I'd find that really useful too. In the name of brevity
of course.

Stephen.

Jun 27 '08 #19

P: n/a
Checkout Boost's Assign Library. You can do these:
vector<intv;
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.
I can't find a definition anwyhere of what the += operator does with
vectors. I'd be happy if, say, v += 2 iterated over the vector and
added the value 2 to each element. similarly if v *= 5 multiplied all
elements then I'd find that really useful too. In the name of brevity
of course.

Stephen.
Jun 27 '08 #20

P: n/a
In article <52b853c6-adcc-4628-9585-
47**********@m36g2000hse.googlegroups.com>, ke****@audiospillage.com
says...

[ ... ]
I can't find a definition anwyhere of what the += operator does with
vectors.
Unless you provide an overloaded operator+= that does something, it
simply generates an error.
I'd be happy if, say, v += 2 iterated over the vector and
added the value 2 to each element. similarly if v *= 5 multiplied all
elements then I'd find that really useful too. In the name of brevity
of course.
If that's what you want, take a look at valarray.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 27 '08 #21

P: n/a
stephen b <ke****@audiospillage.comwrote:
Checkout Boost's Assign Library. You can do these:
vector<intv;
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.

I can't find a definition anwyhere of what the += operator does with
vectors. I'd be happy if, say, v += 2 iterated over the vector and
added the value 2 to each element. similarly if v *= 5 multiplied all
elements then I'd find that really useful too. In the name of brevity
of course.
vector doesn't have an op+= or op*=. Use transform instead:

transform(vec.begin(), vec.end(), vec.begin(), bind2nd(plus<int>(), 2));

The above adds two to each element.

transform(vec.begin(), vec.end(), vec.begin(),
bind2nd(multiplies<int>(), 5));

The above multiplies each element by 5.

You should probably consider using valarray if you are doing this a lot
though.
Jun 27 '08 #22

P: n/a
On May 25, 2:59 am, stephen b <ker...@audiospillage.comwrote:
Checkout Boost's Assign Library. You can do these:
vector<intv;
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.
I can't find a definition anwyhere of what the += operator
does with vectors.
There isn't any, of course, but there is one for string, and it
doesn't take too much imagination to extend it to vector.

There is a well defined meaning for the comma operator,
however. And the above breaks it. It also breaks the rule that
x += y should have the same behavior as x = x + y, modulo the
fact that in one, x is evaluated twice, and in the other only
once. The fact that:
v += 1,2,3,4,5,6,7,8,9;
and
v = 1,2,3,4,5,6,7,8,9;
mean completely different things is pure obfuscation, and won't
be allowed by any reasonable coding guideline.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #23

P: n/a
James Kanze schrieb:
>>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.
>Good, yet possibly bad. Good for vector. Bad if it isn't
more general.

It will definitely be more general. I've not really looked at
it myself, so I don't know the details, but I think the idea is
that it will work for any type which has a two iterator
constructor.
No, you have to write an extra sequence constructor in this form:

struct Container
{
Container(initializer_list<Typeseq)
{
// do something with seq.begin(), .end() and .size(), ex.:
assign(seq.begin(), seq.end());
}
}

From what I have read, an initializer can be used quite everywhere, so
you can pass it to a function or return it:

std::vector<intv = { 1, 2, 3 };
v.append( {4, 5, 6} );

SetColor( {1.0, 0.0, 0.0} ); // sets a RGB color value for red

--
Thomas
Jun 27 '08 #24

P: n/a
On May 25, 3:13*am, James Kanze <james.ka...@gmail.comwrote:
On May 25, 2:59 am, stephen b <ker...@audiospillage.comwrote:
Checkout Boost's Assign Library. You can do these:
vector<intv;
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.
I can't find a definition anwyhere of what the += operator
does with vectors.

There isn't any, of course but there is one for string, and it doesn't
take too much imagination to extend it to vector.
OK

v = vector<float>;
v += 0.1, 0.9, 2.3;

adds 3 elements to an emtpy vector.

v += 3.2, 4.2, 5.6;

adds 3 more elements.. same as String.

There is a well defined meaning for the comma operator,
however. *And the above breaks it. *It also breaks the rule that
x += y should have the same behavior as x = x + y, modulo the
fact that in one, x is evaluated twice, and in the other only
once. *The fact that:
* * v += 1,2,3,4,5,6,7,8,9;
and
* * v = 1,2,3,4,5,6,7,8,9;
mean completely different things is pure obfuscation, and won't
be allowed by any reasonable coding guideline.

You've lost me. What does v = 1,2,3,4,5,6,7,8,9; do?

Stephen.
Jun 27 '08 #25

P: n/a
On May 24, 7:18*pm, "Daniel T." <danie...@earthlink.netwrote:
stephen b <ker...@audiospillage.comwrote:
Checkout Boost's Assign Library. You can do these:
vector<intv;
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.
I can't find a definition anwyhere of what the += operator does with
vectors. I'd be happy if, say, v += 2 iterated over the vector and
added the value 2 to each element. *similarly if v *= 5 multiplied all
elements then I'd find that really useful too. *In the name of brevity
of course.

vector doesn't have an op+= or op*=. Use transform instead:

transform(vec.begin(), vec.end(), vec.begin(), bind2nd(plus<int>(), 2));

The above adds two to each element.

transform(vec.begin(), vec.end(), vec.begin(),
* * * bind2nd(multiplies<int>(), 5));

The above multiplies each element by 5.

You should probably consider using valarray if you are doing this a lot
though.
OK, in light of recent discussion expecting vector += 2 to add to each
element makes little sense really. Thanks for the valarray tip.

Stephen.
Jun 27 '08 #26

P: n/a
Hi!

stephen b schrieb:
You've lost me. What does v = 1,2,3,4,5,6,7,8,9; do?
It won't compile. It would try to assign "1" to "v", then evaluate the
expression "2", then evaluate the expression "3", then evaluate the
expression "4", then evaluate the expression "5", then evaluate the
expression "6", then evaluate the expression "7", then evaluate the
expression "8", and then evaluate the expression "9".

Those expressions are obviously simple to evaluate. But if there was a
vector<T>::operator = (T const t), it could return some strange object
(against all expectations) which could in turn implement the "operator
,". That way the expression could as well mean to first clear the vector
and then append all values.

Frank
Jun 27 '08 #27

P: n/a
Hi!

Thomas J. Gritzan schrieb:
std::vector<intv = { 1, 2, 3 };
v.append( {4, 5, 6} );
Which would actually be a good way to append multiple known values.

Frank
Jun 27 '08 #28

P: n/a
On May 25, 7:35 pm, stephen b <ker...@audiospillage.comwrote:
On May 25, 3:13 am, James Kanze <james.ka...@gmail.comwrote:
On May 25, 2:59 am, stephen b <ker...@audiospillage.comwrote:
Checkout Boost's Assign Library. You can do these:
vector<intv;
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.
I can't find a definition anwyhere of what the += operator
does with vectors.
There isn't any, of course but there is one for string, and
it doesn't take too much imagination to extend it to vector.
OK
v = vector<float>;
v += 0.1, 0.9, 2.3;
adds 3 elements to an emtpy vector.
v += 3.2, 4.2, 5.6;
adds 3 more elements.. same as String.
Except that that's not what it does with string. If s is an
std::string:
s += 'a', 'b', 'c' ;
adds one element to the string ('a'), then evaluates 'b' and
'c', and ignores the results. It's well defined behavior in
standard C++. And while it doesn't make much sense here, I have
seen things like:
s += f(), g(), h() ;
where the functions have side effects. (I don't like it. IMHO,
any use of comma as an operator is a source of confusion, and
should be banned. But I have seen it.)
There is a well defined meaning for the comma operator,
however. And the above breaks it. It also breaks the rule that
x += y should have the same behavior as x = x + y, modulo the
fact that in one, x is evaluated twice, and in the other only
once. The fact that:
v += 1,2,3,4,5,6,7,8,9;
and
v = 1,2,3,4,5,6,7,8,9;
mean completely different things is pure obfuscation, and won't
be allowed by any reasonable coding guideline.
You've lost me. What does v = 1,2,3,4,5,6,7,8,9; do?
It converts 1 to a vector (OK: the conversion is illegal), and
assigns it to v. It then evaluates the expression 2, and throws
out the results, then the expression 3, etc.

As written, it's not very useful, but if you replace the numeric
constants with more complex expressions, with side effects,
there are people who use it.

IMHO, the best solution is just to ban the use of comma as an
operator. Which still wouldn't make it acceptable as an
overloaded operator, because there'd still be the question as to
whether any given comma was an operator or punctuation.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #29

P: n/a
Hi!

James Kanze schrieb:
And while it doesn't make much sense here, I have
seen things like:
s += f(), g(), h() ;
where the functions have side effects. (I don't like it. IMHO,
any use of comma as an operator is a source of confusion, and
should be banned. But I have seen it.)
Yeah. I tried to use the comma operator in the initializer list of a
class constructor. Like:

Foo::Foo(int i)
: count( (InitWhatever(), i) )
{}

Later I changed this to:

int initAndReturn(int i)
{
InitWhatever();
return i;
}
Foo::Foo(int i)
: count(initAndReturn(i))
{}

So, although I see a use for the operator here to make up for the
restrictive syntax for constructors, there always seems to be a better
way to trigger the same side effects (write a wrapper function). This
leads to the conclusion: the comma operator is only overloaded to
generate some "neat syntax" (e.g. for assigning values), and that always
breaks habit. Thus use it with care!

Frank
Jun 27 '08 #30

This discussion thread is closed

Replies have been disabled for this discussion.