Creating unary function by binding-2nd to class member

M

Marcin Gil

Hi!

I have the code like this
(obvious things like ctor/dtor removed)

typedef struct _NODE
{
int val;
int index;
} Node;

struct A:
{
std::vector<Node*> Nodes;

bool EqIndex(const Node* ptr, int idx) const
{ return ptr->index == idx; };

int foo();
}

I would like to write like this:

int A::foo()
{
...
std::find_if(Nodes.begin(), Nodes.end(), bind2nd(&A:EqIndex, 5));
...
}

but got these errors:

1>c:\program files\microsoft visual studio 8\vc\include\functional(303)
: error C2825: '_Fn2': must be a class or namespace when followed by '::'
1> main.cpp(361) : see reference to class template instantiation
'std::binder2nd<_Fn2>' being compiled
1> with
1> [
1> _Fn2=bool (__thiscall A::* )(const Node*,unsigned long)
1> ]
1>c:\program files\microsoft visual studio 8\vc\include\functional(303)
: error C2039: 'first_argument_type' : is not a member of '`global
namespace''
1>c:\program files\microsoft visual studio 8\vc\include\functional(303)
: error C2146: syntax error : missing ',' before identifier
'first_argument_type'
1>c:\program files\microsoft visual studio 8\vc\include\functional(303)
: error C2065: 'first_argument_type' : undeclared identifier
1>c:\program files\microsoft visual studio 8\vc\include\functional(304)
: error C2825: '_Fn2': must be a class or namespace when followed by '::'
1>c:\program files\microsoft visual studio 8\vc\include\functional(304)
: error C2039: 'result_type' : is not a member of '`global namespace''
1>c:\program files\microsoft visual studio 8\vc\include\functional(304)
: error C2146: syntax error : missing ',' before identifier 'result_type'
1>c:\program files\microsoft visual studio 8\vc\include\functional(304)
: error C2065: 'result_type' : undeclared identifier
1>c:\program files\microsoft visual studio 8\vc\include\functional(305)
: error C2955: 'std::unary_function' : use of class template requires
template argument list
1> c:\program files\microsoft visual studio
8\vc\include\functional(21) : see declaration of 'std::unary_function'
1>c:\program files\microsoft visual studio 8\vc\include\functional(307)
: error C2825: '_Fn2': must be a class or namespace when followed by '::'
1>c:\program files\microsoft visual studio 8\vc\include\functional(307)
: error C2143: syntax error : missing ',' before '`global
namespace'::first_argument_type'
1>c:\program files\microsoft visual studio 8\vc\include\functional(308)
: error C2825: '_Fn2': must be a class or namespace when followed by '::'
1>c:\program files\microsoft visual studio 8\vc\include\functional(308)
: error C2143: syntax error : missing ',' before '`global
namespace'::result_type'
1>c:\program files\microsoft visual studio 8\vc\include\functional(309)
: error C2955: 'std::unary_function' : use of class template requires
template argument list
1> c:\program files\microsoft visual studio
8\vc\include\functional(21) : see declaration of 'std::unary_function'
1>c:\program files\microsoft visual studio 8\vc\include\functional(310)
: error C2955: 'std::unary_function' : use of class template requires
template argument list
1> c:\program files\microsoft visual studio
8\vc\include\functional(21) : see declaration of 'std::unary_function'
1>c:\program files\microsoft visual studio 8\vc\include\functional(312)
: error C2825: '_Fn2': must be a class or namespace when followed by '::'
1>c:\program files\microsoft visual studio 8\vc\include\functional(312)
: error C2825: '_Fn2': must be a class or namespace when followed by '::'
1>c:\program files\microsoft visual studio 8\vc\include\functional(312)
: error C2039: 'second_argument_type' : is not a member of '`global
namespace''
1>c:\program files\microsoft visual studio 8\vc\include\functional(312)
: error C2143: syntax error : missing ',' before '&'
1>c:\program files\microsoft visual studio 8\vc\include\functional(330)
: error C2825: '_Fn2': must be a class or namespace when followed by '::'
1>c:\program files\microsoft visual studio 8\vc\include\functional(330)
: error C2039: 'second_argument_type' : is not a member of '`global
namespace''
1>c:\program files\microsoft visual studio 8\vc\include\functional(330)
: error C2146: syntax error : missing ';' before identifier 'value'
1>c:\program files\microsoft visual studio 8\vc\include\functional(330)
: error C4430: missing type specifier - int assumed. Note: C++ does not
support default-int

: error C2664: 'std::find_if' : cannot convert parameter 3 from
'std::binder2nd<_Fn2>' to 'std::binder2nd<_Fn2>'
1> with
1> [
1> _Fn2=bool (__thiscall A::* )(const Node *,unsigned long)
1> ]
1> Cannot copy construct class 'std::binder2nd<_Fn2>' due to
ambiguous copy constructors or no available copy constructor
1> with
1> [
1> _Fn2=bool (__thiscall A::* )(const Node *,unsigned long)
1> ]

What I do wrong?
Using MS Visual Studio 8.

If I write a functor derived from unary_function it works but I'd prefer
using single member function...

Thanks,
-Marcin
 
A

Alf P. Steinbach

* Marcin Gil:
Hi!

I have the code like this
(obvious things like ctor/dtor removed)

typedef struct

'typedef' of 'struct' is a C'ism: don't.


Names starting with underscore followed by uppercase letter are reserved
to the implemention, not to be used by you.

Anyway, use all uppercase names for macros and macros only.

{
int val;
int index;
} Node;

struct A:

Syntax error.

{
std::vector<Node*> Nodes;

bool EqIndex(const Node* ptr, int idx) const
{ return ptr->index == idx; };

Since this function doesn't access anything of the object it's called
on, it doesn't seem likely that it should be a non-static member function.

int foo();
}

Missing semicolon.


I would like to write like this:

int A::foo()
{
...
std::find_if(Nodes.begin(), Nodes.end(), bind2nd(&A:EqIndex, 5));
...
}

Well, first fix the code, then try again.
 
M

Marcin Gil

Alf said:
Well, first fix the code, then try again.
I was writing it from my head.
But I assume it was disrespectful to post non-working code..

Here's the more proper one:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

struct Node {
int val;
int index;
};

struct A
{
std::vector<Node*> Nodes;

A() {};

bool EqIndex(const Node* ptr, int idx) const
{
return (ptr->index == idx);
};

int foo()
{
std::find_if(Nodes.begin(), Nodes.end(), std::bind2nd(&A::EqIndex, 5));
return 0;
};
};

int main(int argc, char* argv[])
{
A a;
a.foo();

return 0;
}


The problem is in the std::find_if(...bind2nd...).
My guess is that it assumes that given type is only class/struct.

I've also tried to use std::mem_fun - no effect.
Do I have to write a functor to use such functionality?

Thanks,
-Marcin
 
A

Alf P. Steinbach

* Marcin Gil:
Alf said:
Well, first fix the code, then try again.
I was writing it from my head.
But I assume it was disrespectful to post non-working code..

Here's the more proper one:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

struct Node {
int val;
int index;
};

struct A
{
std::vector<Node*> Nodes;

A() {};

bool EqIndex(const Node* ptr, int idx) const
{
return (ptr->index == idx);
};

int foo()
{
std::find_if(Nodes.begin(), Nodes.end(),
std::bind2nd(&A::EqIndex, 5));
return 0;
};
};

int main(int argc, char* argv[])
{
A a;
a.foo();

return 0;
}


The problem is in the std::find_if(...bind2nd...).
My guess is that it assumes that given type is only class/struct.

I've also tried to use std::mem_fun - no effect.
Do I have to write a functor to use such functionality?

No, but as I mentioned in the first reply EqIndex isn't naturally a
non-static member function and won't work directly if you insist.

Having fixed that you also need to wrap the function address via
std::ptr_fun.
 
M

Marcin Gil

Alf said:
No, but as I mentioned in the first reply EqIndex isn't naturally a
non-static member function and won't work directly if you insist.

Having fixed that you also need to wrap the function address via
std::ptr_fun.

Thanks!

I've got this working:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

struct Node {
int val;
int index;
};

struct A
{
std::vector<Node*> Nodes;

A() {};

static bool EqIndex(const Node* ptr, int idx)
{
return ptr->index == idx;
};

int foo()
{
std::find_if(Nodes.begin(), Nodes.end(),
std::bind2nd(std::ptr_fun(A::EqIndex), 5));
return 0;
};
};

int main()
{
A a;
a.foo();

return 0;
}
 
D

Default User

Marcin said:
I was writing it from my head.
But I assume it was disrespectful to post non-working code..

It's perfectly fine to post non-working code. What isn't fine is
posting code that isn't what you're problems with.

When your car is having a problem, do you take your neighbor's car into
the shop? I hope not.

Almost every newsreader supports pasting text. Copy the exact code that
giving you trouble and paste that into the message. Then you know
without a doubt that you haven't introduced typing errors.

You may want to review the FAQ:

<http://www.parashift.com/c++-faq-lite/how-to-post.html>




Brian
 

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,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top