Creating unary function by binding-2nd to class member

Discussion in 'C++' started by Marcin Gil, Feb 20, 2007.

  1. Marcin Gil

    Marcin Gil Guest

    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
    Marcin Gil, Feb 20, 2007
    #1
    1. Advertising

  2. * 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.


    > _NODE


    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.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Feb 20, 2007
    #2
    1. Advertising

  3. Marcin Gil

    Marcin Gil Guest

    Alf P. Steinbach wrote:
    > 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
    Marcin Gil, Feb 20, 2007
    #3
  4. * Marcin Gil:
    > Alf P. Steinbach wrote:
    >> 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.



    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Feb 20, 2007
    #4
  5. Marcin Gil

    Marcin Gil Guest

    Alf P. Steinbach wrote:
    >> 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.
    >


    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;
    }
    Marcin Gil, Feb 20, 2007
    #5
  6. Marcin Gil

    Default User Guest

    Marcin Gil wrote:

    > Alf P. Steinbach wrote:
    > > 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..


    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
    Default User, Feb 20, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,684
    Thomas Weidenfeller
    Oct 12, 2005
  2. Fred Ma
    Replies:
    2
    Views:
    2,039
    Fred Ma
    Feb 5, 2004
  3. Replies:
    12
    Views:
    708
    fluden
    Feb 11, 2005
  4. SpOiLeR
    Replies:
    10
    Views:
    789
    SpOiLeR
    Oct 19, 2005
  5. Praetorian
    Replies:
    11
    Views:
    2,329
    James Kanze
    Apr 3, 2008
Loading...

Share This Page