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

mem_fun fun

P: n/a
Hi,

I am having some problem using std::bind1st() and mem_fun. I want to
bind member function calls to some kind of functor so it can be called
later.

The following works fine for me:

class Foo
{
std::string name;
public:
Foo() : name("mike") {}

std::string getName()
{
return name;
}

void setName(std::string n)
{
name = n;
}
};

typedef std::binder1st<std::mem_fun1_t<void, Foo, std::string
SetterFunc;

main()
{
Foo foo;

SetterFunc f = std::bind1st(mem_fun(&Foo::setName), &foo);

std::string test("testing");
f(test);

std::cout << "after call, name is " << foo.getName() <<
std::endl;
}
But when I want to bind the getName() method, I have lots of trouble:

typedef std::binder1st<std::mem_fun_t<std::string, Foo GetterFunc;
GetterFunc y = std::bind1st(mem_func(&Foo::getName), &foo);

I think I don't want to use bind1st because the getName() method takes
no parameters? Is there a std::bind() ?

Also, what if setName() takes "const std::string&" instead of just
"std::string" ? Do I need mem_fun_ref or some const variation of it?

Thanks for any tips.

Sep 18 '07 #1
Share this Question
Share on Google+
8 Replies


P: n/a
flopbucket wrote:
I am having some problem using std::bind1st() and mem_fun. I want to
bind member function calls to some kind of functor so it can be called
later.

The following works fine for me:

class Foo
{
std::string name;
public:
Foo() : name("mike") {}

std::string getName()
{
return name;
}

void setName(std::string n)
{
name = n;
}
};

typedef std::binder1st<std::mem_fun1_t<void, Foo, std::string
SetterFunc;

main()
{
Foo foo;

SetterFunc f = std::bind1st(mem_fun(&Foo::setName), &foo);

std::string test("testing");
f(test);

std::cout << "after call, name is " << foo.getName() <<
std::endl;
}
But when I want to bind the getName() method, I have lots of trouble:

typedef std::binder1st<std::mem_fun_t<std::string, Foo GetterFunc;
GetterFunc y = std::bind1st(mem_func(&Foo::getName), &foo);
What kind of trouble? Why couldn't you post non-working code instead?
I think I don't want to use bind1st because the getName() method takes
no parameters? Is there a std::bind() ?
Why wouldn't you? 'bind1st' makes sure that the member function is
called with the particular instance, 'foo'.
>
Also, what if setName() takes "const std::string&" instead of just
"std::string" ? Do I need mem_fun_ref or some const variation of it?
Probably. Have tried it an failed or what?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 18 '07 #2

P: n/a
What kind of trouble? Why couldn't you post non-working code instead?
>
Thanks for your response, here is a non-working example:

#include<iostream>
#include<functional>
#include<string>

class Foo
{
std::string name_;

public:
Foo() : name_("mike")
{}

std::string getName()
{
return name_;
}
};

typedef std::binder1st<std::mem_fun_t<std::string, Foo GetterFunc;

int main(int, char **)
{
Foo foo();

GetterFunc f = std::bind1st(std::mem_fun(&Foo::getName),
&foo);

std::cout << f() << std::endl;
}

$ g++ tmp.cc
error: no type named `second_argument_type' in `class
std::mem_fun_t<std::string, Foo>'
Basically I would like to place the call foo->getName() into a functor
so I could call it later.

Thanks for any tips.
Sep 18 '07 #3

P: n/a
flopbucket <fl********@hotmail.comwrote:
class Foo
{
std::string name;
public:
Foo() : name("mike") {}

std::string getName()
{
return name;
}

void setName(std::string n)
{
name = n;
}
};
typedef std::binder1st<std::mem_fun_t<std::string, Foo GetterFunc;
GetterFunc y = std::bind1st(mem_func(&Foo::getName), &foo);

I think I don't want to use bind1st because the getName() method takes
no parameters? Is there a std::bind() ?
Correct to the first question, and no to the second. You will have to
make your own binder for this.
Also, what if setName() takes "const std::string&" instead of just
"std::string" ? Do I need mem_fun_ref or some const variation of it?
If setName takes a const string& then you can't use bind1st because you
can't make a reference to a reference. I think that is supposed to be
fixed in the next standard isn't it?
Sep 18 '07 #4

P: n/a
flopbucket wrote:
>What kind of trouble? Why couldn't you post non-working code
instead?

Thanks for your response, here is a non-working example:

#include<iostream>
#include<functional>
#include<string>

class Foo
{
std::string name_;

public:
Foo() : name_("mike")
{}

std::string getName()
{
return name_;
}
};

typedef std::binder1st<std::mem_fun_t<std::string, Foo GetterFunc;

int main(int, char **)
{
Foo foo();

GetterFunc f = std::bind1st(std::mem_fun(&Foo::getName),
&foo);

std::cout << f() << std::endl;
}

$ g++ tmp.cc
error: no type named `second_argument_type' in `class
std::mem_fun_t<std::string, Foo>'
Basically I would like to place the call foo->getName() into a functor
so I could call it later.
Right. Well, the problem is that 'bind1st' (and 'binder1st') need their
argument to be a function of two arguments. Since mem_fun(&Foo::getName)
returns a functor with only one argument, it cannot be use in 'bind1st'.

You probably should consider using 'bind' which overcomes the limitation
of "exactly two arguments" imposed by 'binder1st'. Or you could add
a dummy argument to 'getName', thus making it a function with a second
argument, sort of. A hassle, admittedly.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 18 '07 #5

P: n/a
>
You probably should consider using 'bind' which overcomes the limitation
of "exactly two arguments" imposed by 'binder1st'.

V

Thanks to all for the responses. Is there a std::bind()? Or is that
part of Boost? I'm not finding a std::bind() in my environment. I
guess it's pretty easy to write a simple wrapper for this, but I would
rather use something standard and existing then rolling my own.

Thanks again.
Sep 18 '07 #6

P: n/a
On 2007-09-18 15:38:57 -0400, "Victor Bazarov" <v.********@comAcast.netsaid:
flopbucket wrote:
>I think I don't want to use bind1st because the getName() method takes
no parameters? Is there a std::bind() ?

Why wouldn't you? 'bind1st' makes sure that the member function is
called with the particular instance, 'foo'.
No, that's the problem: bind1st converts a binary function into a unary
function by binding the first argument of the binary function to the
argument passed to bind1st. The resulting object has a function call
operator that takes one argument, and passes it as the second argument
to the binary function. (Whew. That's confusing.)

There is an std::bind() that will do what's needed, but it's not the
current standard (it's in TR1 and slated for C++0x). Calling
std::bind(&Foo::getName, &foo) returns an object whose operator() [with
no arguments] returns (&foo)->getName(). It also works with that second
argument passed by value, in which case it uses a copy, with that
second argument passed as a reference_wrapper<Foo>, in which case it
uses a referece to foo, and with that second argument passed by a smart
pointer (anything that provides an operator-that returns a pointer to
something that getName() can be applied to). For more details, see
chapter 10 of my book, "The Standard C++ Library Extensions".

The drawback here, for the original poster, is that the return type of
std::bind() is unspecified, so it's hard to create named objects of
this type other than as arguments and local variables in template
functions. The following code was written but not compiled:

template <class Op>
std::string apply(Op op)
{
return op();
}

int main()
{
Foo foo;
std::string res = apply(std::bind(&Foo::getName, &foo));
return 0;
}

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

Sep 18 '07 #7

P: n/a
flopbucket wrote:
>You probably should consider using 'bind' which overcomes the
limitation of "exactly two arguments" imposed by 'binder1st'.

V


Thanks to all for the responses. Is there a std::bind()?
If your compiler doesn't have it yet, it will, eventually. It's in the
currently proposed draft. I am guessing we should see it adopted next
year or the year after.
Or is that
part of Boost?
Yes.
I'm not finding a std::bind() in my environment. I
guess it's pretty easy to write a simple wrapper for this, but I would
rather use something standard and existing then rolling my own.
Good idea.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 18 '07 #8

P: n/a


Thanks again for all the replies, very much appreciated.
Sep 19 '07 #9

This discussion thread is closed

Replies have been disabled for this discussion.