mem_fun fun

F

flopbucket

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.
 
V

Victor Bazarov

flopbucket said:
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
 
F

flopbucket

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.
 
D

Daniel T.

flopbucket said:
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?
 
V

Victor Bazarov

flopbucket said:
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
 
F

flopbucket

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.
 
P

Pete Becker

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;
}
 
V

Victor Bazarov

flopbucket said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top