From: ShaunJ on
Hi,

In the following snippet,
for_each(first, last, bind1st(mem_fun_ref(&Foo::fun), arg));
I've found that the GNU implementation of bind1st makes a copy of arg.
In my case, arg has a private copy constructor, because it's a heavy
operation. On top of that, for_each returns a copy of its third
argument rather than a reference to its third argument. Is there any
way to make this work? Is this just a GNU implementation issue, or a
more general problem?

Thanks,
Shaun

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

From: marcin.sfider on
On Aug 4, 6:27 am, ShaunJ <sjack...(a)gmail.com> wrote:
> Hi,
>
> In the following snippet,
> for_each(first, last, bind1st(mem_fun_ref(&Foo::fun), arg));
> I've found that the GNU implementation of bind1st makes a copy of arg.
> In my case, arg has a private copy constructor, because it's a heavy
> operation. On top of that, for_each returns a copy of its third
> argument rather than a reference to its third argument. Is there any
> way to make this work? Is this just a GNU implementation issue, or a
> more general problem?
>
> Thanks,
> Shaun
>
I think it is a general problem. Think of a case when you want to bind
an argument with bind1st and store returned functional object. If it
haven't do a copy it could easly outlive its argument. Other case is
a temporary object which cannot be passed by reference, only by const
reference.

Solution would be to use boost::ref or boost::cref with boost::bind.

Cheers
Sfider


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

From: restor on

> In the following snippet,
> for_each(first, last, bind1st(mem_fun_ref(&Foo::fun), arg));
> I've found that the GNU implementation of bind1st makes a copy of arg.
> In my case, arg has a private copy constructor, because it's a heavy
> operation. On top of that, for_each returns a copy of its third
> argument rather than a reference to its third argument. Is there any
> way to make this work? Is this just a GNU implementation issue, or a
> more general problem?

Hi, It is not particular to GNU this is how the functions are defined.
The following should work:

for_each(first, last, std::bind1st(std::mem_fun(&Foo::fun), &arg));

This way you will be copying pointer rather than an object itself. But
if I can suggest using boost::bind or std::tr1::bind? It would be even
cleaner then:

for_each( first, last, boost::bind(&Foo::fun, &arg, _1) );

Regards,
&rzej


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

From: ShaunJ on
On Aug 4, 12:18 pm, restor <akrze...(a)gmail.com> wrote:
> > In the following snippet,
> > for_each(first, last, bind1st(mem_fun_ref(&Foo::fun), arg));
> > I've found that the GNU implementation of bind1st makes a copy of arg.
> > In my case, arg has a private copy constructor, because it's a heavy
> > operation. On top of that, for_each returns a copy of its third
> > argument rather than a reference to its third argument. Is there any
> > way to make this work? Is this just a GNU implementation issue, or a
> > more general problem?
>
> Hi, It is not particular to GNU this is how the functions are defined.
> The following should work:
>
> for_each(first, last, std::bind1st(std::mem_fun(&Foo::fun), &arg));

That worked. Thanks! For the record, complete code follows.

> This way you will be copying pointer rather than an object itself. But
> if I can suggest using boost::bind or std::tr1::bind? It would be even
> cleaner then:
>
> for_each( first, last, boost::bind(&Foo::fun, &arg, _1) );

I haven't made the jump to boost yet. It's look more appealing every
day.

Cheers,
Shaun

#include <iostream>

using namespace std;

struct Foo {
Foo() { }
void fun(const char* s) const { cout << s << endl; }
static void sfun(const char* s) { cout << s << endl; }
private:
Foo(const Foo&);
};

int main(int argc, char** argv)
{
Foo foo;
for_each(argv, argv + argc,
bind1st(mem_fun(&Foo::fun), &foo));
for_each(argv, argv + argc, ptr_fun(&Foo::sfun));
return 0;
}


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

From: Chris Vine on
On Wed, 4 Aug 2010 20:12:58 CST
ShaunJ <sjackman(a)gmail.com> wrote:
[snip]
> struct Foo {
> Foo() { }
> void fun(const char* s) const { cout << s << endl; }
[snip]
> };
>
> int main(int argc, char** argv)
> {
> Foo foo;
> for_each(argv, argv + argc,
> bind1st(mem_fun(&Foo::fun), &foo));
[snip]
> }

That's interesting. The fact that you can bind an argument to the
version of std::mem_fun for unary member functions with std::bind2nd
implies that you can bind an object pointer instead with std::bind1st,
so that you can use it with containers of argument rather than
containers of object, but does the standard actually require this
construction to work?

Chris

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