From: imbunche on
Hi,

The following code applys a conversion function to elements on a vector
depending on its index, as follows:

int i;
vector<sometype> val;
for (i=0; i<tokens.size(); ++i)
{
val[i] = convert(i,v[i]);
// or ... val.push_back(convert(i,v[i]));
}

The best I have achieved (with my limited STL knowledge is:
transform(tokens.begin(), tokens.end(),
back_inserter(val), // where to put results.
bind (convert,
0, _1));
Which is useless of course becauss it fixes the first parameter of
convert to 0, ... I need some kind of i++ but I cannot find the way
.....

Please help,
thx in advance.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Vladimir Marko on
imbunche wrote:
> Hi,
>
> The following code applys a conversion function to elements on a vector
> depending on its index, as follows:
>
> int i;
> vector<sometype> val;
> for (i=0; i<tokens.size(); ++i)
> {
> val[i] = convert(i,v[i]);
> // or ... val.push_back(convert(i,v[i]));
> }
>
> The best I have achieved (with my limited STL knowledge is:
> transform(tokens.begin(), tokens.end(),
> back_inserter(val), // where to put results.
> bind (convert,
> 0, _1));
> Which is useless of course becauss it fixes the first parameter of
> convert to 0, ... I need some kind of i++ but I cannot find the way
> ....

You need the boost::counting_iterator and the second overload
of transform:
std::transform(
tokens.begin(),tokens.end(), // first1, last1
boost::counting_iterator<std::size_t>(0u), // first2
tokens.begin(), // result
boost::bind(convert,_2,_1) // binary_op
//< in which namespace are _1 and _2? Never mind.
);
See http://www.boost.org/libs/iterator/doc/counting_iterator.html .

Cheers,
Vladimir Marko


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Greg Herlihy on
imbunche wrote:
> Hi,
>
> The following code applys a conversion function to elements on a vector
> depending on its index, as follows:
>
> int i;
> vector<sometype> val;
> for (i=0; i<tokens.size(); ++i)
> {
> val[i] = convert(i,v[i]);
> // or ... val.push_back(convert(i,v[i]));
> }
>
> The best I have achieved (with my limited STL knowledge is:
> transform(tokens.begin(), tokens.end(),
> back_inserter(val), // where to put results.
> bind (convert,
> 0, _1));
> Which is useless of course becauss it fixes the first parameter of
> convert to 0, ... I need some kind of i++ but I cannot find the way
> ....

I think that std::accumulate could be used to solve this problem. For
example, I would first declare a function (or a function object) that
accepts an index value and a reference to a "sometype" type as
parameters, and which returns the accumulated value (serving as the
index) incremented by one:

int AccumulateProc(int acc, sometype& t)
{
t = convert(acc, t);
return acc+1;
}

And then pass this routine (or object) to std::accumlate like so:

#include <vector>
#include <numeric>
...

std::vector<sometype> v;
...

int acc;

acc = accumulate( v.begin(), v.end(), 0, AccumulateProc);

The sometype elements in the vector will have been converted in place.
Note that for this code to compile, sometype must be assignable (that
is, it may be necessary implement operator=() for sometype's).

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ulrich Eckhardt on
imbunche wrote:
> The following code applys a conversion function to elements on a vector
> depending on its index,
^^^^^^^^^^^^^^^^^^^^^^^ this is the problem!

> as follows:
>
> int i;
> vector<sometype> val;
> for (i=0; i<tokens.size(); ++i)
> {
> val[i] = convert(i,v[i]);
> // or ... val.push_back(convert(i,v[i]));
> }
>
> The best I have achieved (with my limited STL knowledge is:
> transform(tokens.begin(), tokens.end(),
> back_inserter(val), // where to put results.
> bind (convert,
> 0, _1));
> Which is useless of course becauss it fixes the first parameter of
> convert to 0, ... I need some kind of i++ but I cannot find the way
> ....

The point is that this is not a single conversion but many different
ones, because they depend on the position of the element inside the vector.
Sorry, but I think that the algorithms of the stdlibrary are simply not
the right tool here. I also couldn't think of a way to express it
stdlibrary-like, as it typically deals with sequences that are mostly
not even accessible via an index.

Uli


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: dasjotre on
imbunche wrote:
> Hi,
>
> The following code applys a conversion function to elements on a vector
> depending on its index, as follows:
>
> int i;
> vector<sometype> val;
> for (i=0; i<tokens.size(); ++i)
> {
> val[i] = convert(i,v[i]);

don't you mean val[i] = convert(i, tokens[i]); ?

> // or ... val.push_back(convert(i,v[i]));
> }
>
> The best I have achieved (with my limited STL knowledge is:
> transform(tokens.begin(), tokens.end(),
> back_inserter(val), // where to put results.
> bind (convert,
> 0, _1));
> Which is useless of course becauss it fixes the first parameter of
> convert to 0, ... I need some kind of i++ but I cannot find the way
> ....
if you make convert an object it can hold the index
struct convert
{
convert() : index(0){}

sometype operator()(tokens::value_type&)
{
use index and increment it at the end
}

size_t index;
};

extend from unary_function, you don't need bind


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]