Q: Map of pointers to member functions

Discussion in 'C++' started by Jim, Mar 10, 2005.

  1. Jim

    Jim Guest

    I'd like to create a map of strings to member function pointers, so that I
    can call a specific function based on a string. I'm compiling this using MS
    Visual C++ 7.0 (VS.NET 2002)

    class Foo;

    /// Prototype for functions that extract a parameter from a module
    typedef const void (Foo::*PARAM_GETTER)(std::string&);

    /// A map of strings to parameter getters
    typedef std::map<std::string, PARAM_GETTER> ParamGetterMap;

    And then,

    class Foo
    {
    protected:
    ParamGetterMap m_getterMap;
    };

    class Bar : public AnotherBaseClass, public Foo
    {
    private:
    // getter/setter helpers
    void GetBar(std::string& strValue) { strValue = "something"; }
    };

    And finally,

    Bar::Bar()
    {
    // Fill the parameter maps
    m_getterMap.insert(make_pair("bar", GetBar)); // COMPLILE ERROR HERE
    }

    I get the following compile error:

    C:\Microsoft Visual Studio .NET\Vc7\include\utility(41) : error C2440:
    'initializing' : cannot
    convert from 'void (__thiscall Bar::* const )(std::string &)' to
    'PARAM_GETTER '
    Types pointed to are unrelated; conversion requires reinterpret_cast,
    C-style cast or
    function-style cast
    Bar.cpp(41) : see
    reference to function template instantiation 'std::pair<_Ty1,_Ty2>::pair
    (const std::pair<char,void
    (__thiscall Bar::* )(std::string &)> &)' being compiled
    with
    [
    _Ty1=const std::string,
    _Ty2=PARAM_GETTER
    ]
    C:\Microsoft Visual Studio .NET\Vc7\include\utility(41) : error C2439:
    'std::pair<_Ty1,_Ty2>::second' : member could not be initialized
    with
    [
    _Ty1=const std::string,
    _Ty2=PARAM_GETTER
    ]
    C:\Microsoft Visual Studio .NET\Vc7\include\utility(56) : see
    declaration of
    'std::pair<_Ty1,_Ty2>::second'
    with
    [
    _Ty1=const std::string,
    _Ty2=PARAM_GETTER
    ]

    Can anyone point out what I'm doing wrong here?

    Thx x 10^6

    --
    Jim Johnson
    Jim, Mar 10, 2005
    #1
    1. Advertising

  2. Jim wrote:
    > m_getterMap.insert(make_pair("bar", GetBar)); // COMPLILE ERROR HERE


    GetBar is only defined in Bar but PARAM_GETTER is a function pointer to
    a member function of Foo:

    > typedef const void (Foo::*PARAM_GETTER)(std::string&);


    I hope that helps you.
    Michael Etscheid, Mar 10, 2005
    #2
    1. Advertising

  3. Jim

    Jim Guest

    > Jim wrote:
    > > m_getterMap.insert(make_pair("bar", GetBar)); // COMPLILE ERROR HERE

    >
    > GetBar is only defined in Bar but PARAM_GETTER is a function pointer to
    > a member function of Foo:
    >
    > > typedef const void (Foo::*PARAM_GETTER)(std::string&);

    >
    > I hope that helps you.
    >


    A little; but it doesn't point to a solution.

    I've used a similar technique before and it worked; I had to cast the
    function pointer to a specific type to clear up a different error, however
    here I can't get even that close (the cast gives me severe warning).



    --
    Jim Johnson
    Jim, Mar 10, 2005
    #3
  4. Jim wrote:
    > [...]
    > Bar::Bar()
    > {
    > // Fill the parameter maps
    > m_getterMap.insert(make_pair("bar", GetBar)); // COMPLILE ERROR HERE


    The address of a non-static member function cannot be obtained by using
    only its name. The format is &Bar::GetBar. It is required.

    > }
    Victor Bazarov, Mar 10, 2005
    #4
  5. Jim

    Jim Guest

    > Jim wrote:
    > > [...]
    > > Bar::Bar()
    > > {
    > > // Fill the parameter maps
    > > m_getterMap.insert(make_pair("bar", GetBar)); // COMPLILE ERROR HERE

    >
    > The address of a non-static member function cannot be obtained by using
    > only its name. The format is &Bar::GetBar. It is required.
    >
    > > }

    >


    Thanks; but using the syntax you specified makes no difference (same compile
    error).



    --
    Jim Johnson
    Jim, Mar 10, 2005
    #5
  6. Jim

    red floyd Guest

    Jim wrote:
    >>Jim wrote:
    >>
    >>> m_getterMap.insert(make_pair("bar", GetBar)); // COMPLILE ERROR HERE

    >>
    >>GetBar is only defined in Bar but PARAM_GETTER is a function pointer to
    >>a member function of Foo:
    >>
    >> > typedef const void (Foo::*PARAM_GETTER)(std::string&);

    >>
    >>I hope that helps you.
    >>

    >
    >
    > A little; but it doesn't point to a solution.
    >
    > I've used a similar technique before and it worked; I had to cast the
    > function pointer to a specific type to clear up a different error, however
    > here I can't get even that close (the cast gives me severe warning).
    >
    >
    >


    No, what he's saying is your map translates from std::string to Foo::*
    member.
    You're trying to pass it a Bar::* member. The typedef in the error
    message is hiding it. Look at the def of PARAM_GETTER, and the def of
    GetBar().
    red floyd, Mar 10, 2005
    #6
  7. Jim wrote:
    >>Jim wrote:
    >>
    >>>[...]
    >>>Bar::Bar()
    >>>{
    >>> // Fill the parameter maps
    >>> m_getterMap.insert(make_pair("bar", GetBar)); // COMPLILE ERROR HERE

    >>
    >>The address of a non-static member function cannot be obtained by using
    >>only its name. The format is &Bar::GetBar. It is required.
    >>
    >>
    >>>}

    >>

    >
    > Thanks; but using the syntax you specified makes no difference (same compile
    > error).


    Sorry, solved a wrong problem :)

    A pointer to member of a derived class is not convertible to a pointer
    to member of the base class. It does work that way for pointers to
    objects, but works _in_reverse_ for pointers to members.

    To convert a pointer to member you need a static_cast.
    --------------------------------------------------------
    Bar::Bar()
    {
    // Fill the parameter maps
    m_getterMap.insert(std::make_pair("bar",
    static_cast<PARAM_GETTER>(&Bar::GetBar))); // NO ERROR HERE
    }
    --------------------------------------------------------

    V
    Victor Bazarov, Mar 10, 2005
    #7
    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. Victor Bazarov
    Replies:
    1
    Views:
    415
    Jonathan Mcdougall
    Jul 25, 2003
  2. David White
    Replies:
    0
    Views:
    3,075
    David White
    Jul 24, 2003
  3. Hamish
    Replies:
    3
    Views:
    548
    Alf P. Steinbach
    Jan 25, 2008
  4. Hicham Mouline
    Replies:
    0
    Views:
    413
    Hicham Mouline
    Apr 23, 2009
  5. paul
    Replies:
    8
    Views:
    693
    Alf P. Steinbach
    Apr 30, 2009
Loading...

Share This Page