473,383 Members | 1,862 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

function object for [] and *

Hello,

I need help to replace the following code:

int *idx; //...
for (int i = 0; i < n; i++, ++out)
out = in[idx[i]];

with something like:

int *idx; //...
std::transform(idx, idx + n, out, ...);

I think the operator for transform should look something like:

__gnu_cxx::compose1(in[], *idx)

So, I think, I need a function object to apply the [] operator to "in",
given an int and another one to apply the * operator to each element in
"idx".

Thanks in advance,
Rares Vernica
Jun 27 '08 #1
8 1224
On Jun 23, 2:22*pm, Rares Vernica <ra...@ics.uci.eduwrote:
Hello,

I need help to replace the following code:

* int *idx; //...
* for (int i = 0; i < n; i++, ++out)
* * out = in[idx[i]];

with something like:

* int *idx; //... * *
* std::transform(idx, idx + n, out, ...);

I think the operator for transform should look something like:

* * __gnu_cxx::compose1(in[], *idx)

So, I think, I need a function object to apply the [] operator to "in",
given an int and another one to apply the * operator to each element in
"idx".
Here's a first cut assuming the contents of in and out are doubles.
If they're not, change accordingly...

struct Functor
{
std::vector<doubleconst & m_in;

// constructor
Functor (std::vector<doubleconst & in) : m_in (in)
{}

// functor operator
double operator () (int i) const
{
return in [i];
}
}

std::transform (idx, idx + n, out, Functor (in));

Make sure out has enough room in out or use std::back_inserter (out).

HTH
Jun 27 '08 #2
An**********@gmail.com wrote:
On Jun 23, 2:22 pm, Rares Vernica <ra...@ics.uci.eduwrote:
>Hello,

I need help to replace the following code:

int *idx; //...
for (int i = 0; i < n; i++, ++out)
out = in[idx[i]];

with something like:

int *idx; //...
std::transform(idx, idx + n, out, ...);

I think the operator for transform should look something like:

__gnu_cxx::compose1(in[], *idx)

So, I think, I need a function object to apply the [] operator to "in",
given an int and another one to apply the * operator to each element in
"idx".
Here's a first cut assuming the contents of in and out are doubles.
If they're not, change accordingly...

struct Functor
{
std::vector<doubleconst & m_in;

// constructor
Functor (std::vector<doubleconst & in) : m_in (in)
{}

// functor operator
double operator () (int i) const
{
return in [i];
}
}

std::transform (idx, idx + n, out, Functor (in));

Make sure out has enough room in out or use std::back_inserter (out).

HTH
You might also try something like so (untested):

std::transform(idx, idx+n, out, boost::bind(&in_type::operator[], in, _1));
Jun 27 '08 #3

"Rares Vernica" <ra***@ics.uci.edua écrit dans le message de news:
y1*************@ics.uci.edu...
Hello,

I need help to replace the following code:

int *idx; //...
for (int i = 0; i < n; i++, ++out)
out = in[idx[i]];

with something like:

int *idx; //...
std::transform(idx, idx + n, out, ...);

I think the operator for transform should look something like:

__gnu_cxx::compose1(in[], *idx)

So, I think, I need a function object to apply the [] operator to "in",
given an int and another one to apply the * operator to each element in
"idx".

Thanks in advance,
Rares Vernica

here is a generic way to do what you want using only stl stuff.

using namespace std;

// here is the functor, I assume idx is always of type int, if not, replace
it with a template parameter

template<typename T_out, typename T_in>
struct Get : public binary_function<int, T_in, T_out>
{
// binary_function is needed by bind2nd
T_out operator()(int idx, T_in in) const
{
return in[idx];
}
};

int main()
{
int idx[3] = {0,1,2};
int in[3] = {5,4,3};
int out[3];

transform(idx, idx+3, out, bind2nd(Get<int,int*>(), &in[0]));

cout << out[0] <<"\n" <<out[1] <<"\n" <<out[2] <<"\n";
return 0;
}

this print:
5
4
3

---------------------------

Eric Pruneau
Jun 27 '08 #4
Eric Pruneau wrote:
"Rares Vernica" <ra***@ics.uci.edua écrit dans le message de news:
y1*************@ics.uci.edu...
>Hello,

I need help to replace the following code:

int *idx; //...
for (int i = 0; i < n; i++, ++out)
out = in[idx[i]];

with something like:

int *idx; //...
std::transform(idx, idx + n, out, ...);

I think the operator for transform should look something like:

__gnu_cxx::compose1(in[], *idx)

So, I think, I need a function object to apply the [] operator to "in",
given an int and another one to apply the * operator to each element in
"idx".

Thanks in advance,
Rares Vernica


here is a generic way to do what you want using only stl stuff.
That is good, but it should be kept in mind that boost's bind will be in
the next standard library as part of the "stl". Unless you're being
told not to use it I would definitely recommend getting it and learning
how. It's power and simplicity (as long as you're not trying to read
it) is not even remotely reached by the current library's binders.
Jun 27 '08 #5
On Jun 23, 8:22 pm, Rares Vernica <ra...@ics.uci.eduwrote:
I need help to replace the following code:
int *idx; //...
for (int i = 0; i < n; i++, ++out)
out = in[idx[i]];
with something like:
int *idx; //...
std::transform(idx, idx + n, out, ...);
Why? The first is simple and easily readable. The second is
likely to be obfuscation, unless you can find a very good name
for the functional object. Unless this is a "standard"
transformation, occuring in many different places in your
application, you're almost certainly better off sticking with
the orginal loop.

At least for now. I believe that the next version of the
standard will have some sort of support for lambdas; using
transform with a lambda function here would make a lot of sense.
Moving the transformation itself out into a separate object
doesn't, however, unless that object is generally usable and can
be given a good name which reflects what it does. And trying to
simulate lambda with variations of boost::bind is probably not
going to result in anything readable.
I think the operator for transform should look something like:
__gnu_cxx::compose1(in[], *idx)
In other words, it should be some obscure object that many C++
programmers aren't familiar with, rather than straightforward
code which anyone can understand.

--
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 #6
On Jun 23, 10:34 pm, Noah Roberts <u...@example.netwrote:
AnonMail2...@gmail.com wrote:
On Jun 23, 2:22 pm, Rares Vernica <ra...@ics.uci.eduwrote:
I need help to replace the following code:
int *idx; //...
for (int i = 0; i < n; i++, ++out)
out = in[idx[i]];
with something like:
int *idx; //...
std::transform(idx, idx + n, out, ...);
I think the operator for transform should look something like:
__gnu_cxx::compose1(in[], *idx)
So, I think, I need a function object to apply the []
operator to "in", given an int and another one to apply the
* operator to each element in "idx".
Here's a first cut assuming the contents of in and out are
doubles. If they're not, change accordingly...
struct Functor
{
std::vector<doubleconst & m_in;
// constructor
Functor (std::vector<doubleconst & in) : m_in (in)
{}
// functor operator
double operator () (int i) const
{
return in [i];
}
}
std::transform (idx, idx + n, out, Functor (in));
Make sure out has enough room in out or use std::back_inserter (out).
You might also try something like so (untested):
std::transform(idx, idx+n, out, boost::bind(&in_type::operator[], in, _1));
Which won't work if in_type is a C style array (or a pointer).
(Otherwise, a simple, direct application of boost::bind is still
readable enough that I would consider it more or less
acceptable. Although I don't see anything wrong with the
original code, and I'd probably wait until we get lambda
expressions to upgrade it.)

--
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 #7
On Jun 24, 5:57 pm, Noah Roberts <u...@example.netwrote:
Eric Pruneau wrote:
"Rares Vernica" <ra...@ics.uci.edua écrit dans le message de news:
y1rve00roxp....@ics.uci.edu...
I need help to replace the following code:
int *idx; //...
for (int i = 0; i < n; i++, ++out)
out = in[idx[i]];
with something like:
int *idx; //...
std::transform(idx, idx + n, out, ...);
I think the operator for transform should look something like:
__gnu_cxx::compose1(in[], *idx)
So, I think, I need a function object to apply the []
operator to "in", given an int and another one to apply the
* operator to each element in "idx".
here is a generic way to do what you want using only stl stuff.
That is good,
Actually, it's mostly good for obfuscation, moving the
transformation logic out of the function, and forcing the reader
to look elsewhere to know what is going on.
but it should be kept in mind that boost's bind will be in the
next standard library as part of the "stl". Unless you're
being told not to use it I would definitely recommend getting
it and learning how. It's power and simplicity (as long as
you're not trying to read it) is not even remotely reached by
the current library's binders.
Boost's bind definitely belongs in everyone's tool kit, but it
has it's limits as well---if the operator[] in question is the
built in version, for example, it won't work. The next version
of the standard will also include some support for lambda
expressions, which would be an even more general 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 #8
On Jun 25, 9:46*am, James Kanze <james.ka...@gmail.comwrote:
On Jun 24, 5:57 pm, Noah Roberts <u...@example.netwrote:
Eric Pruneau wrote:
"Rares Vernica" <ra...@ics.uci.edua écrit dans le message de news:
y1rve00roxp....@ics.uci.edu...
>I need help to replace the following code:
>*int *idx; //...
>*for (int i = 0; i < n; i++, ++out)
>* *out = in[idx[i]];
>with something like:
>*int *idx; //...
>*std::transform(idx, idx + n, out, ...);
>I think the operator for transform should look something like:
>* *__gnu_cxx::compose1(in[], *idx)
>So, I think, I need a function object to apply the []
>operator to "in", given an int and another one to apply the
>* operator to each element in "idx".
here is a generic way to do what you want using only stl stuff.
That is good,

Actually, it's mostly good for obfuscation, moving the
transformation logic out of the function, and forcing the reader
to look elsewhere to know what is going on.
but it should be kept in mind that boost's bind will be in the
next standard library as part of the "stl". *Unless you're
being told not to use it I would definitely recommend getting
it and learning how. *It's power and simplicity (as long as
you're not trying to read it) is not even remotely reached by
the current library's binders.

Boost's bind definitely belongs in everyone's tool kit, but it
has it's limits as well---if the operator[] in question is the
built in version, for example, it won't work. *The next version
of the standard will also include some support for lambda
expressions, which would be an even more general solution.
It will also not work if operator[] has been overloaded for const and
non const 'this' (as it is usually the case). You need an explicit
(and ugly) cast then. The OP bind example also has a problem if used
with any container but plain arrays: bind closes its arguments by copy
so it will cause the container to be copied: use boost::ref or
boost::cref.

With boost lambda you can do:

namespace ll = boost::lambda;
std::transform(idx, idx+n, out, ll::ret<whatever>(ll::var(in)[_1]));

where 'whatever' is the result type for operator[]. In this case the
const qualified value_type of 'in' should be enough. For std::vector
(and standard containers in general) and builtin arrays, you do not
need 'ret<>':

namespace ll= boost::lambda;

std::vector<intm = ...;
std::vector<intidx = ...;
std::vector<intout = ...;
std::transform(idx.begin(), idx.end(), out.begin(), ll::var(m)
[ll::_1]);

Which doesn't look that ugly.

--
gpd
Jun 27 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Fernando Rodriguez | last post by:
Hi, I need to traverse the methods defined in a class and its superclasses. This is the code I'm using: # An instance of class B should be able to check all the methods defined in B #and A,...
7
by: vegetax | last post by:
I i need a decorator that adds a local variable in the function it decorates, probably related with nested scopes, for example: def dec(func): def wrapper(obj = None): if not obj : obj = Obj()...
9
by: Derek Hart | last post by:
I wish to execute code from a string. The string will have a function name, which will return a string: Dim a as string a = "MyFunctionName(param1, param2)" I have seen a ton of people...
3
by: domeceo | last post by:
can anyone tell me why I cannot pass values in a setTimeout function whenever I use this function it says "menu is undefined" after th alert. function imgOff(menu, num) { if (document.images) {...
2
by: laredotornado | last post by:
Hello, I am looking for a cross-browser way (Firefox 1+, IE 5.5+) to have my Javascript function execute from the BODY's "onload" method, but if there is already an onload method defined, I would...
28
by: Larax | last post by:
Best explanation of my question will be an example, look below at this simple function: function SetEventHandler(element) { // some operations on element element.onclick = function(event) {
5
by: Daz | last post by:
Hi everyone. My query is very straight forward (I think). What's the difference between someFunc.blah = function(){ ; } and
4
by: alex | last post by:
I am so confused with these three concept,who can explained it?thanks so much? e.g. var f= new Function("x", "y", "return x * y"); function f(x,y){ return x*y } var f=function(x,y){
7
by: VK | last post by:
I was getting this effect N times but each time I was in rush to just make it work, and later I coudn't recall anymore what was the original state I was working around. This time I nailed the...
12
by: Bryan Parkoff | last post by:
I write my large project in C++ source code. My C++ source code contains approximate four thousand small functions. Most of them are inline. I define variables and functions in the global scope....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.