Thread: More help on pointer to function in map

  1. #1
    Registered User
    Join Date
    Jul 2003
    Posts
    450

    More help on pointer to function in map

    I am having difficulty with the syntax for calling a pointer to a function in a map.
    Code:
    vector<string*> * BeverageUserInterface::ParseMessage(vector<string*>* MessageIn)
    {
       vector<string *>::iterator CommandPos;
       BeverageDriverMap::iterator CommandLookUp;
       
       for (CommandPos = (*MessageIn).begin(); CommandPos != (*MessageIn).end(); ++CommandPos)
       {
       	   CommandLookUp = BeverageDriverTable.find(*CommandPos);	           
               
    	   if (CommandLookUp != BeverageDriverTable.end())
    	   {
    	       *(*CommandLookUp->second());//syntax problem here
    	   } 
       }
       return MessageOut;
    }
    tried
    *(*(CommandLookUp->second)());

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Why are you passing vectors as pointers and not references? Also why string * instead of string? Both of these are making it much more difficult on yourself.

    Also what is the exact syntax error?

    And where is MessageOut declared?

    edit:
    try:
    Code:
    *(CommandLookUp->second());
    Last edited by Thantos; 12-08-2004 at 09:59 AM.

  3. #3
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    MessageOut is a private member of the class. Really it is acting as a kind of local global variable which may be kind of ify in terms of incapsulation but I could not figure out a way to implement my DriverTable with function pointers with all different signatures.

    I can't really remember my reasoning for using a pointer to a vector instead of a refrence It just was more natural for me.

    Same with the string * I am passing by refrence to avoid calls to the copy constructor.

    After I complete this assignment I may go back and change the types to refrences to simplify some of the coding.

    I get the following error with your suggestion
    /home/curlious/assignment7/src/userinterface.cpp:72: error: must use .* or ->* to call pointer-to-member function in `(&CommandLookUp)->std::_Rb_tree_iterator<_Tp>::operator-> [with _Tp = std::pair<string* const, void (BeverageUserInterface::*)()>]()->std::pair<string* const, void (BeverageUserInterface::*)()>::second (...)'

    My attempt gave this error.
    /home/curlious/assignment7/src/userinterface.cpp:72: error: must use .* or ->* to call pointer-to-member function in `(&CommandLookUp)->std::_Rb_tree_iterator<_Tp>::operator-> [with _Tp = std::pair<string* const, void (BeverageUserInterface::*)()>]()->std::pair<string* const, void (BeverageUserInterface::*)()>::second (...)'

  4. #4
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Well by passing a pointer to a vector you have only caused yourself more headache (since you have to deference it). Using a string * might save you the copy constructor call but thats about all. But the complexity of the result code does not warrent such an action.

    Also both errors you posted appear to be the same.

    This is just a guess based off of the cryptic error:
    Code:
    *((*CommandLookUp)->second());

  5. #5
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by curlious
    Same with the string * I am passing by refrence to avoid calls to the copy constructor.
    If speed is of such extreme importance to you, write your program in C or assembler using C-style strings.
    If not, avoid unnecessary optimizations that obfuscate your code.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  6. #6
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    I also thought it was important to save on memory usage.
    You have convinced me Ill rework the code.
    Code:
    *((*CommandLookUp)->second());
    I get the following error now. And am still curious as to the correct syntax though I will go back now and implement the refrences instead.
    /home/curlious/assignment7/src/userinterface.cpp:72: error: base operand of `->' has non-pointer type `std::pair<string* const, void (BeverageUserInterface::*)()>'

    Thanks for the advice and input!

    :rolleyes:
    Last edited by curlious; 12-08-2004 at 10:39 AM.

  7. #7
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    It looks like changing everything to refrences at this point is going to be very difficult. I made a quick attempt and it broke my code fiercly.

  8. #8
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    It might be difficult but it'll be worth it

  9. #9
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    Ok so I am attempting to make the change in small steps here is what I have done.
    Code:
    vector<string*> * BeverageUserInterface::ParseMessage(vector<string*>& MessageIn)
    {
       vector<string *>::iterator CommandPos;
       BeverageDriverMap::iterator CommandLookUp;
       
       for (CommandPos = (*MessageIn).begin(); CommandPos != (*MessageIn).end(); ++CommandPos)
       {
       	   CommandLookUp = BeverageDriverTable.find(*CommandPos);	           
               
    	   if (CommandLookUp != BeverageDriverTable.end())
    	   {
    	       *(*(CommandLookUp->second)());
    	   } 
       }
       return MessageOut;
    }
    I get the same error:
    /home/curlious/assignment7/src/userinterface.cpp:72: error: must use .* or ->* to call pointer-to-member function in `(&CommandLookUp)->std::_Rb_tree_iterator<_Tp>::operator-> [with _Tp = std::pair<string* const, void (BeverageUserInterface::*)()>]()->std::pair<string* const, void (BeverageUserInterface::*)()>::second (...)'


    Also in main I am not sure how to convert to refrences as I must initialize the refrence to the vector
    Code:
    #include "userinterface.h"
     #include "BeerLogic.h"
     #include "ourstr.h"
     #include <vector>
     using std::vector;
    int main(int argc, char * argv[])
    {
      
        BeverageUserInterface MyBeverageInterface;
        BeerLogic MyBeverageLogic;
        vector<string*> * UIMessageIn;
        vector<string*> * UIMessageOut;//if I change this to vector<string *>& UIMessageOut how do I initialize it?
        const string QUIT="8";        
        do
        {  
           (*UIMessageOut).clear();
           (*UIMessageOut).push_back(new string("ShowMenu"));
           (*UIMessageOut).push_back(new string("GetMenuItem"));
           
           
           UIMessageIn = MyBeverageInterface.ParseMessage(*UIMessageOut);
           UIMessageOut = MyBeverageLogic.PerformOption(UIMessageIn);
           MyBeverageInterface.ParseMessage(*UIMessageOut);    
        }while (*(*UIMessageIn)[0] != "QUIT");
           
        return EXIT_SUCCESS;
    }

  10. #10
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Ok heres a quicky example:

    Code:
    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    void foo (vector<string>& vs)
    {
      for (vector<string>::iterator bar = vs.begin();
             bar != vs.end();
             bar++
            )
        cout<<bar<<endl;
    
    }
    
    int main()
    {
      vector<string> vStr;  // I have an object called vStr that is a vector of strings
    
      vStr.push_back("Hello World!");
      vStr.push_back("How are you doing today?");
      vStr.push_back("I'm doing good, finals are here.");
      vStr.push_back("Cool.");
    
      foo(vStr);
    }
    Hope that helps shows you how to use references

  11. #11
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Oh as for your program. Where is
    Code:
    vector<string*> * UIMessageOut;
    being assigned a memory location that has been allocated for a vector<string*>?

  12. #12
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    good point I did not initialize UIMessageIn and Out in main.
    I have changed this.
    If I do not use a pointer I must use a refrence for UIMessage
    because it would be impractical to pass the entire vector back as a return type
    so I can not simply declare
    vector<string *> UIMessage;
    because BeerLogic returns a pointer (at the moment -> to be refrence)
    to a Messagevector

    so my question stands concerning initializing the refrence to the vector in main
    here is the code at the moment.
    Code:
    #include "userinterface.h"
     #include "BeerLogic.h"
     #include "ourstr.h"
     #include <vector>
     using std::vector;
    int main(int argc, char * argv[])
    {
      
        BeverageUserInterface MyBeverageInterface;
        BeerLogic MyBeverageLogic;
        vector<string*> * UIMessageIn = new vector<string *>;
        vector<string*> * UIMessageOut= new vector<string *>;
        const string QUIT="8";        
        do
        {  
           (*UIMessageOut).clear();
           (*UIMessageOut).push_back(new string("ShowMenu"));
           (*UIMessageOut).push_back(new string("GetMenuItem"));
           
           
           UIMessageIn = MyBeverageInterface.ParseMessage(*UIMessageOut);
           UIMessageOut = MyBeverageLogic.PerformOption(*UIMessageIn);
           MyBeverageInterface.ParseMessage(*UIMessageOut);    
        }while (*(*UIMessageIn)[0] != "QUIT");
           
        return EXIT_SUCCESS;
    }
    I want to change the pointers to refrences for UIMessages but still do not know how to init the refrence to a vector.

    Code:
    vector<string*> * BeverageUserInterface::ParseMessage(vector<string*>& MessageIn)
    {
       vector<string *>::iterator CommandPos;
       BeverageDriverMap::iterator CommandLookUp;
       
       for (CommandPos = MessageIn.begin(); CommandPos != MessageIn.end(); ++CommandPos)
       {
       	   CommandLookUp = BeverageDriverTable.find(*CommandPos);	           
               
    	   if (CommandLookUp != BeverageDriverTable.end())
    	   {
    	       *(*(CommandLookUp->second)());
    	   } 
       }
       return MessageOut;
    }
    fixed the initialization of the iterator taking into account the refrence
    trying to derefrence the pointer to a function refered to by CommandLookUp->second is still a problem
    /home/curlious/assignment7/src/userinterface.cpp:72: error: must use .* or ->* to call pointer-to-member function in `(&CommandLookUp)->std::_Rb_tree_iterator<_Tp>::operator-> [with _Tp = std::pair<string* const, void (BeverageUserInterface::*)()>]()->std::pair<string* const, void (BeverageUserInterface::*)()>::second (...)'

  13. #13
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    I think I understand my first question.
    I need to create a vector<string *> then
    create a refrence that points to it.

    Code:
     #include "userinterface.h"
     #include "BeerLogic.h"
     #include "ourstr.h"
     #include <vector>
     using std::vector;
    int main(int argc, char * argv[])
    {
      
        BeverageUserInterface MyBeverageInterface;
        BeerLogic MyBeverageLogic;
        vector<string*> UIMessageIn;
        vector<string*>& RefUIMessageIn = &UIMessageIn;
        vector<string*> UIMessageOut;
        vector<string*>& RefUIMessageOut = &UIMessageOut;
        
        const string QUIT="8";        
        do
        {  
           UIMessageOut.clear();
           UIMessageOut.push_back(new string("ShowMenu"));
           UIMessageOut.push_back(new string("GetMenuItem"));
           
           
           RefUIMessageIn = MyBeverageInterface.ParseMessage(RefUIMessageOut);
           RefUIMessageOut = MyBeverageLogic.PerformOption(RefUIMessageIn);
           MyBeverageInterface.ParseMessage(RefUIMessageOut);    
        }while (*(UIMessageIn)[0] != "QUIT");
           
        return EXIT_SUCCESS;
    }
    Nope this is all wrong.

    But still stumped on the second question.
    Last edited by curlious; 12-08-2004 at 12:18 PM.

  14. #14
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    One quick thing I spotted:

    Code:
    vector<string*> UIMessageIn;
    vector<string*>& RefUIMessageIn = &UIMessageIn;
    vector<string*> UIMessageOut;
    vector<string*>& RefUIMessageOut = &UIMessageOut;
    Not the proper way to assign values to a reference, remove the &'s marked in red above.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  15. #15
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    Thanks this is diffucult and turning to be nearly as obfusce.
    That gets me well on the way to converting it.
    Can anyone help me with the derefrencing the map-second function pointer?
    Code:
    vector<string*> & BeverageUserInterface::ParseMessage(vector<string*>& MessageIn)
    {
       vector<string *>::iterator CommandPos;
       BeverageDriverMap::iterator CommandLookUp;
       
       for (CommandPos = MessageIn.begin(); CommandPos != MessageIn.end(); ++CommandPos)
       {
       	   CommandLookUp = BeverageDriverTable.find(*CommandPos);	           
               
    	   if (CommandLookUp != BeverageDriverTable.end())
    	   {
    	       *(*(CommandLookUp->second)());
    	   } 
       }
       return *MessageOut;
    /home/curlious/assignment7/src/userinterface.cpp:72: error: must use .* or ->* to call pointer-to-member function in `(&CommandLookUp)->std::_Rb_tree_iterator<_Tp>::operator-> [with _Tp = std::pair<string* const, void (BeverageUserInterface::*)()>]()->std::pair<string* const, void (BeverageUserInterface::*)()>::second (...)'
    Last edited by curlious; 12-08-2004 at 12:48 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  3. Calling a Thread with a Function Pointer.
    By ScrollMaster in forum Windows Programming
    Replies: 6
    Last Post: 06-10-2006, 08:56 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Compiler "Warnings"
    By Jeremy G in forum A Brief History of Cprogramming.com
    Replies: 24
    Last Post: 04-24-2005, 01:09 PM