How to store methods as function pointers in a map container?












17















I want to be able to call functions based on the data I read from file.
So for each item type, I want to call the desired reader method.
I wrote this code, but it does not compile where I want to add function pointers to the map. What is wrong?



#include <vector>
#include <map>
#include <iostream>
class reader
{

std::map< std::string, void(*)()> functionCallMap; // function pointer
void readA(){ std::cout << "reading An";};
void readB(){ std::cout << "reading Bn";};;
public:
reader()
{
*functionCallMap["A"] = &reader::readA;*
*functionCallMap["B"] = &reader::readB;*
}

void read()
{
auto (*f) = functionCallMap["A"];
(*f)();
}



};


I am filling the map at Constructor.










share|improve this question




















  • 5





    A pointer to a non-member function is not the same as a pointer to a member function. The big difference is that member functions needs objects to be called on. You can solve it by using std::function instead, together with either lambda expressions or std::bind.

    – Some programmer dude
    Nov 16 '18 at 11:25
















17















I want to be able to call functions based on the data I read from file.
So for each item type, I want to call the desired reader method.
I wrote this code, but it does not compile where I want to add function pointers to the map. What is wrong?



#include <vector>
#include <map>
#include <iostream>
class reader
{

std::map< std::string, void(*)()> functionCallMap; // function pointer
void readA(){ std::cout << "reading An";};
void readB(){ std::cout << "reading Bn";};;
public:
reader()
{
*functionCallMap["A"] = &reader::readA;*
*functionCallMap["B"] = &reader::readB;*
}

void read()
{
auto (*f) = functionCallMap["A"];
(*f)();
}



};


I am filling the map at Constructor.










share|improve this question




















  • 5





    A pointer to a non-member function is not the same as a pointer to a member function. The big difference is that member functions needs objects to be called on. You can solve it by using std::function instead, together with either lambda expressions or std::bind.

    – Some programmer dude
    Nov 16 '18 at 11:25














17












17








17


3






I want to be able to call functions based on the data I read from file.
So for each item type, I want to call the desired reader method.
I wrote this code, but it does not compile where I want to add function pointers to the map. What is wrong?



#include <vector>
#include <map>
#include <iostream>
class reader
{

std::map< std::string, void(*)()> functionCallMap; // function pointer
void readA(){ std::cout << "reading An";};
void readB(){ std::cout << "reading Bn";};;
public:
reader()
{
*functionCallMap["A"] = &reader::readA;*
*functionCallMap["B"] = &reader::readB;*
}

void read()
{
auto (*f) = functionCallMap["A"];
(*f)();
}



};


I am filling the map at Constructor.










share|improve this question
















I want to be able to call functions based on the data I read from file.
So for each item type, I want to call the desired reader method.
I wrote this code, but it does not compile where I want to add function pointers to the map. What is wrong?



#include <vector>
#include <map>
#include <iostream>
class reader
{

std::map< std::string, void(*)()> functionCallMap; // function pointer
void readA(){ std::cout << "reading An";};
void readB(){ std::cout << "reading Bn";};;
public:
reader()
{
*functionCallMap["A"] = &reader::readA;*
*functionCallMap["B"] = &reader::readB;*
}

void read()
{
auto (*f) = functionCallMap["A"];
(*f)();
}



};


I am filling the map at Constructor.







c++ function pointers






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 16 '18 at 18:15









Josh Darnell

9,78962855




9,78962855










asked Nov 16 '18 at 11:22









Ring Zero.Ring Zero.

12110




12110








  • 5





    A pointer to a non-member function is not the same as a pointer to a member function. The big difference is that member functions needs objects to be called on. You can solve it by using std::function instead, together with either lambda expressions or std::bind.

    – Some programmer dude
    Nov 16 '18 at 11:25














  • 5





    A pointer to a non-member function is not the same as a pointer to a member function. The big difference is that member functions needs objects to be called on. You can solve it by using std::function instead, together with either lambda expressions or std::bind.

    – Some programmer dude
    Nov 16 '18 at 11:25








5




5





A pointer to a non-member function is not the same as a pointer to a member function. The big difference is that member functions needs objects to be called on. You can solve it by using std::function instead, together with either lambda expressions or std::bind.

– Some programmer dude
Nov 16 '18 at 11:25





A pointer to a non-member function is not the same as a pointer to a member function. The big difference is that member functions needs objects to be called on. You can solve it by using std::function instead, together with either lambda expressions or std::bind.

– Some programmer dude
Nov 16 '18 at 11:25












4 Answers
4






active

oldest

votes


















20














You can use std::function with a lambda or std::bind :



class reader
{
std::map<std::string, std::function<void()>> functionCallMap;

void readA() { std::cout << "reading An"; };
void readB() { std::cout << "reading Bn"; };

public:
reader()
{
functionCallMap["A"] = [this]() { readA(); };
functionCallMap["B"] = std::bind(&reader::readB, this);
}

void read()
{
functionCallMap["A"]();
functionCallMap["B"]();
}
};





share|improve this answer
























  • I prefer your solution because it's more C++ish and cleaner than raw function pointer. Anyway lamba should be preferred to std::bind (Scott Meyer's Effective Modern C++)

    – Moia
    Nov 16 '18 at 11:46













  • Yes, It is a nice solution. But, according to Jason Turner, bind is expensive both in compile time and memory usage.

    – Ring Zero.
    Nov 16 '18 at 17:45













  • @RingZero You should still use std::function instead of a function pointer, I would strongly advise switching the marked answer to this one for future readers. Using actual function pointers is bad for a number of reasons, but one issue is that you can't bind to anything that is a lambda pointer with variable capture. You will notice that std::function doesn't need the class pointer in the signature using the above.

    – opa
    Nov 16 '18 at 21:58



















17














You need to use pointers to member functions, like this:



class reader
{
using FuncPtr = void(reader::*)(); // function pointer
std::map< std::string, FuncPtr> functionCallMap;
void readA(){ std::cout << "reading An"; }
void readB(){ std::cout << "reading Bn"; }
public:
reader()
{
functionCallMap["A"] = &reader::readA;
functionCallMap["B"] = &reader::readB;
}

void read()
{
auto f = functionCallMap["A"];
(this->*f)();
}
};

int main()
{
reader r;
r.read();
}





share|improve this answer

































    9














    There are two answers so far, this and this.



    The obvious difference is that one uses std::function and other uses function pointers. This is not the important difference!!



    The key point is that the member functions are non-static member functions. So, they are not of type void().



    They are of type void(reader::*)(). Thus, they can be only called if an object of type is reader is given; one can understand this somewhat as a hidden parameter.



    The first answer just fixes the problem by specifying the correct type. This can be done using function pointers (as presented) or using std::function (The latter is much more expensive!).



    The second answer fixes the problem by binding the function pointer to the particular instance of the class. After binding, the type is then indeed void(). This cannot be done using raw function pointers (because they can only point to a function and not an object/function pair!).






    share|improve this answer


























    • Also note that the timing of the binding is a design choice. I.E. does the application always want to bind the object storing the function pointers or potentially another one?

      – Keith
      Nov 16 '18 at 21:15



















    1














    I ended up with this solution. It does the job, but I have some doubts over its aesthetics. Anyway, to sum up, I ended up with this code:



    #include <map>
    #include <iostream>
    #include <functional>
    class reader
    {
    std::map< std::string, std::function<void(std::string tableName)>> functionCallMap; // function pointer
    void readA(const std::string tableName){ std::cout << "reading:" << tableName<< "n"; }
    void readB(const std::string tableName){ std::cout << "reading:" << tableName <<"n"; }
    public:
    reader()
    {
    functionCallMap["A"] = std::bind(&reader::readA, this, std::placeholders::_1);
    functionCallMap["B"] = std::bind(&reader::readA, this, std::placeholders::_1);
    }

    void read()
    {
    const std::string table_name = "A";
    functionCallMap[table_name](table_name);
    }
    };

    int main()
    {
    reader r;
    r.read();
    }


    I pass the table name to the reader, it is nicely done with the bind and placeholder.






    share|improve this answer
























    • You should use string references in your callback functions instead of a copy. And as Moia said, you really should use a lambda instead of std::bind. About the aesthetics, I don't understand why you need a map of function since readA and readB are the same. Moreover readB is never used so why don't just put so code of readA into read?

      – Siliace
      Nov 18 '18 at 14:14













    • @Siliace, It seems lambda and bind has its own pros and cons, read A and read B are going to read different kinds of tables, different formats and invoke different factory methods down the line.

      – Ring Zero.
      Nov 18 '18 at 14:56












    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53336880%2fhow-to-store-methods-as-function-pointers-in-a-map-container%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    20














    You can use std::function with a lambda or std::bind :



    class reader
    {
    std::map<std::string, std::function<void()>> functionCallMap;

    void readA() { std::cout << "reading An"; };
    void readB() { std::cout << "reading Bn"; };

    public:
    reader()
    {
    functionCallMap["A"] = [this]() { readA(); };
    functionCallMap["B"] = std::bind(&reader::readB, this);
    }

    void read()
    {
    functionCallMap["A"]();
    functionCallMap["B"]();
    }
    };





    share|improve this answer
























    • I prefer your solution because it's more C++ish and cleaner than raw function pointer. Anyway lamba should be preferred to std::bind (Scott Meyer's Effective Modern C++)

      – Moia
      Nov 16 '18 at 11:46













    • Yes, It is a nice solution. But, according to Jason Turner, bind is expensive both in compile time and memory usage.

      – Ring Zero.
      Nov 16 '18 at 17:45













    • @RingZero You should still use std::function instead of a function pointer, I would strongly advise switching the marked answer to this one for future readers. Using actual function pointers is bad for a number of reasons, but one issue is that you can't bind to anything that is a lambda pointer with variable capture. You will notice that std::function doesn't need the class pointer in the signature using the above.

      – opa
      Nov 16 '18 at 21:58
















    20














    You can use std::function with a lambda or std::bind :



    class reader
    {
    std::map<std::string, std::function<void()>> functionCallMap;

    void readA() { std::cout << "reading An"; };
    void readB() { std::cout << "reading Bn"; };

    public:
    reader()
    {
    functionCallMap["A"] = [this]() { readA(); };
    functionCallMap["B"] = std::bind(&reader::readB, this);
    }

    void read()
    {
    functionCallMap["A"]();
    functionCallMap["B"]();
    }
    };





    share|improve this answer
























    • I prefer your solution because it's more C++ish and cleaner than raw function pointer. Anyway lamba should be preferred to std::bind (Scott Meyer's Effective Modern C++)

      – Moia
      Nov 16 '18 at 11:46













    • Yes, It is a nice solution. But, according to Jason Turner, bind is expensive both in compile time and memory usage.

      – Ring Zero.
      Nov 16 '18 at 17:45













    • @RingZero You should still use std::function instead of a function pointer, I would strongly advise switching the marked answer to this one for future readers. Using actual function pointers is bad for a number of reasons, but one issue is that you can't bind to anything that is a lambda pointer with variable capture. You will notice that std::function doesn't need the class pointer in the signature using the above.

      – opa
      Nov 16 '18 at 21:58














    20












    20








    20







    You can use std::function with a lambda or std::bind :



    class reader
    {
    std::map<std::string, std::function<void()>> functionCallMap;

    void readA() { std::cout << "reading An"; };
    void readB() { std::cout << "reading Bn"; };

    public:
    reader()
    {
    functionCallMap["A"] = [this]() { readA(); };
    functionCallMap["B"] = std::bind(&reader::readB, this);
    }

    void read()
    {
    functionCallMap["A"]();
    functionCallMap["B"]();
    }
    };





    share|improve this answer













    You can use std::function with a lambda or std::bind :



    class reader
    {
    std::map<std::string, std::function<void()>> functionCallMap;

    void readA() { std::cout << "reading An"; };
    void readB() { std::cout << "reading Bn"; };

    public:
    reader()
    {
    functionCallMap["A"] = [this]() { readA(); };
    functionCallMap["B"] = std::bind(&reader::readB, this);
    }

    void read()
    {
    functionCallMap["A"]();
    functionCallMap["B"]();
    }
    };






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 16 '18 at 11:40









    SiliaceSiliace

    47237




    47237













    • I prefer your solution because it's more C++ish and cleaner than raw function pointer. Anyway lamba should be preferred to std::bind (Scott Meyer's Effective Modern C++)

      – Moia
      Nov 16 '18 at 11:46













    • Yes, It is a nice solution. But, according to Jason Turner, bind is expensive both in compile time and memory usage.

      – Ring Zero.
      Nov 16 '18 at 17:45













    • @RingZero You should still use std::function instead of a function pointer, I would strongly advise switching the marked answer to this one for future readers. Using actual function pointers is bad for a number of reasons, but one issue is that you can't bind to anything that is a lambda pointer with variable capture. You will notice that std::function doesn't need the class pointer in the signature using the above.

      – opa
      Nov 16 '18 at 21:58



















    • I prefer your solution because it's more C++ish and cleaner than raw function pointer. Anyway lamba should be preferred to std::bind (Scott Meyer's Effective Modern C++)

      – Moia
      Nov 16 '18 at 11:46













    • Yes, It is a nice solution. But, according to Jason Turner, bind is expensive both in compile time and memory usage.

      – Ring Zero.
      Nov 16 '18 at 17:45













    • @RingZero You should still use std::function instead of a function pointer, I would strongly advise switching the marked answer to this one for future readers. Using actual function pointers is bad for a number of reasons, but one issue is that you can't bind to anything that is a lambda pointer with variable capture. You will notice that std::function doesn't need the class pointer in the signature using the above.

      – opa
      Nov 16 '18 at 21:58

















    I prefer your solution because it's more C++ish and cleaner than raw function pointer. Anyway lamba should be preferred to std::bind (Scott Meyer's Effective Modern C++)

    – Moia
    Nov 16 '18 at 11:46







    I prefer your solution because it's more C++ish and cleaner than raw function pointer. Anyway lamba should be preferred to std::bind (Scott Meyer's Effective Modern C++)

    – Moia
    Nov 16 '18 at 11:46















    Yes, It is a nice solution. But, according to Jason Turner, bind is expensive both in compile time and memory usage.

    – Ring Zero.
    Nov 16 '18 at 17:45







    Yes, It is a nice solution. But, according to Jason Turner, bind is expensive both in compile time and memory usage.

    – Ring Zero.
    Nov 16 '18 at 17:45















    @RingZero You should still use std::function instead of a function pointer, I would strongly advise switching the marked answer to this one for future readers. Using actual function pointers is bad for a number of reasons, but one issue is that you can't bind to anything that is a lambda pointer with variable capture. You will notice that std::function doesn't need the class pointer in the signature using the above.

    – opa
    Nov 16 '18 at 21:58





    @RingZero You should still use std::function instead of a function pointer, I would strongly advise switching the marked answer to this one for future readers. Using actual function pointers is bad for a number of reasons, but one issue is that you can't bind to anything that is a lambda pointer with variable capture. You will notice that std::function doesn't need the class pointer in the signature using the above.

    – opa
    Nov 16 '18 at 21:58













    17














    You need to use pointers to member functions, like this:



    class reader
    {
    using FuncPtr = void(reader::*)(); // function pointer
    std::map< std::string, FuncPtr> functionCallMap;
    void readA(){ std::cout << "reading An"; }
    void readB(){ std::cout << "reading Bn"; }
    public:
    reader()
    {
    functionCallMap["A"] = &reader::readA;
    functionCallMap["B"] = &reader::readB;
    }

    void read()
    {
    auto f = functionCallMap["A"];
    (this->*f)();
    }
    };

    int main()
    {
    reader r;
    r.read();
    }





    share|improve this answer






























      17














      You need to use pointers to member functions, like this:



      class reader
      {
      using FuncPtr = void(reader::*)(); // function pointer
      std::map< std::string, FuncPtr> functionCallMap;
      void readA(){ std::cout << "reading An"; }
      void readB(){ std::cout << "reading Bn"; }
      public:
      reader()
      {
      functionCallMap["A"] = &reader::readA;
      functionCallMap["B"] = &reader::readB;
      }

      void read()
      {
      auto f = functionCallMap["A"];
      (this->*f)();
      }
      };

      int main()
      {
      reader r;
      r.read();
      }





      share|improve this answer




























        17












        17








        17







        You need to use pointers to member functions, like this:



        class reader
        {
        using FuncPtr = void(reader::*)(); // function pointer
        std::map< std::string, FuncPtr> functionCallMap;
        void readA(){ std::cout << "reading An"; }
        void readB(){ std::cout << "reading Bn"; }
        public:
        reader()
        {
        functionCallMap["A"] = &reader::readA;
        functionCallMap["B"] = &reader::readB;
        }

        void read()
        {
        auto f = functionCallMap["A"];
        (this->*f)();
        }
        };

        int main()
        {
        reader r;
        r.read();
        }





        share|improve this answer















        You need to use pointers to member functions, like this:



        class reader
        {
        using FuncPtr = void(reader::*)(); // function pointer
        std::map< std::string, FuncPtr> functionCallMap;
        void readA(){ std::cout << "reading An"; }
        void readB(){ std::cout << "reading Bn"; }
        public:
        reader()
        {
        functionCallMap["A"] = &reader::readA;
        functionCallMap["B"] = &reader::readB;
        }

        void read()
        {
        auto f = functionCallMap["A"];
        (this->*f)();
        }
        };

        int main()
        {
        reader r;
        r.read();
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 16 '18 at 21:20

























        answered Nov 16 '18 at 11:27









        snake_stylesnake_style

        1,170511




        1,170511























            9














            There are two answers so far, this and this.



            The obvious difference is that one uses std::function and other uses function pointers. This is not the important difference!!



            The key point is that the member functions are non-static member functions. So, they are not of type void().



            They are of type void(reader::*)(). Thus, they can be only called if an object of type is reader is given; one can understand this somewhat as a hidden parameter.



            The first answer just fixes the problem by specifying the correct type. This can be done using function pointers (as presented) or using std::function (The latter is much more expensive!).



            The second answer fixes the problem by binding the function pointer to the particular instance of the class. After binding, the type is then indeed void(). This cannot be done using raw function pointers (because they can only point to a function and not an object/function pair!).






            share|improve this answer


























            • Also note that the timing of the binding is a design choice. I.E. does the application always want to bind the object storing the function pointers or potentially another one?

              – Keith
              Nov 16 '18 at 21:15
















            9














            There are two answers so far, this and this.



            The obvious difference is that one uses std::function and other uses function pointers. This is not the important difference!!



            The key point is that the member functions are non-static member functions. So, they are not of type void().



            They are of type void(reader::*)(). Thus, they can be only called if an object of type is reader is given; one can understand this somewhat as a hidden parameter.



            The first answer just fixes the problem by specifying the correct type. This can be done using function pointers (as presented) or using std::function (The latter is much more expensive!).



            The second answer fixes the problem by binding the function pointer to the particular instance of the class. After binding, the type is then indeed void(). This cannot be done using raw function pointers (because they can only point to a function and not an object/function pair!).






            share|improve this answer


























            • Also note that the timing of the binding is a design choice. I.E. does the application always want to bind the object storing the function pointers or potentially another one?

              – Keith
              Nov 16 '18 at 21:15














            9












            9








            9







            There are two answers so far, this and this.



            The obvious difference is that one uses std::function and other uses function pointers. This is not the important difference!!



            The key point is that the member functions are non-static member functions. So, they are not of type void().



            They are of type void(reader::*)(). Thus, they can be only called if an object of type is reader is given; one can understand this somewhat as a hidden parameter.



            The first answer just fixes the problem by specifying the correct type. This can be done using function pointers (as presented) or using std::function (The latter is much more expensive!).



            The second answer fixes the problem by binding the function pointer to the particular instance of the class. After binding, the type is then indeed void(). This cannot be done using raw function pointers (because they can only point to a function and not an object/function pair!).






            share|improve this answer















            There are two answers so far, this and this.



            The obvious difference is that one uses std::function and other uses function pointers. This is not the important difference!!



            The key point is that the member functions are non-static member functions. So, they are not of type void().



            They are of type void(reader::*)(). Thus, they can be only called if an object of type is reader is given; one can understand this somewhat as a hidden parameter.



            The first answer just fixes the problem by specifying the correct type. This can be done using function pointers (as presented) or using std::function (The latter is much more expensive!).



            The second answer fixes the problem by binding the function pointer to the particular instance of the class. After binding, the type is then indeed void(). This cannot be done using raw function pointers (because they can only point to a function and not an object/function pair!).







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 16 '18 at 16:02









            pushkin

            4,688113054




            4,688113054










            answered Nov 16 '18 at 12:30









            Handy999Handy999

            67118




            67118













            • Also note that the timing of the binding is a design choice. I.E. does the application always want to bind the object storing the function pointers or potentially another one?

              – Keith
              Nov 16 '18 at 21:15



















            • Also note that the timing of the binding is a design choice. I.E. does the application always want to bind the object storing the function pointers or potentially another one?

              – Keith
              Nov 16 '18 at 21:15

















            Also note that the timing of the binding is a design choice. I.E. does the application always want to bind the object storing the function pointers or potentially another one?

            – Keith
            Nov 16 '18 at 21:15





            Also note that the timing of the binding is a design choice. I.E. does the application always want to bind the object storing the function pointers or potentially another one?

            – Keith
            Nov 16 '18 at 21:15











            1














            I ended up with this solution. It does the job, but I have some doubts over its aesthetics. Anyway, to sum up, I ended up with this code:



            #include <map>
            #include <iostream>
            #include <functional>
            class reader
            {
            std::map< std::string, std::function<void(std::string tableName)>> functionCallMap; // function pointer
            void readA(const std::string tableName){ std::cout << "reading:" << tableName<< "n"; }
            void readB(const std::string tableName){ std::cout << "reading:" << tableName <<"n"; }
            public:
            reader()
            {
            functionCallMap["A"] = std::bind(&reader::readA, this, std::placeholders::_1);
            functionCallMap["B"] = std::bind(&reader::readA, this, std::placeholders::_1);
            }

            void read()
            {
            const std::string table_name = "A";
            functionCallMap[table_name](table_name);
            }
            };

            int main()
            {
            reader r;
            r.read();
            }


            I pass the table name to the reader, it is nicely done with the bind and placeholder.






            share|improve this answer
























            • You should use string references in your callback functions instead of a copy. And as Moia said, you really should use a lambda instead of std::bind. About the aesthetics, I don't understand why you need a map of function since readA and readB are the same. Moreover readB is never used so why don't just put so code of readA into read?

              – Siliace
              Nov 18 '18 at 14:14













            • @Siliace, It seems lambda and bind has its own pros and cons, read A and read B are going to read different kinds of tables, different formats and invoke different factory methods down the line.

              – Ring Zero.
              Nov 18 '18 at 14:56
















            1














            I ended up with this solution. It does the job, but I have some doubts over its aesthetics. Anyway, to sum up, I ended up with this code:



            #include <map>
            #include <iostream>
            #include <functional>
            class reader
            {
            std::map< std::string, std::function<void(std::string tableName)>> functionCallMap; // function pointer
            void readA(const std::string tableName){ std::cout << "reading:" << tableName<< "n"; }
            void readB(const std::string tableName){ std::cout << "reading:" << tableName <<"n"; }
            public:
            reader()
            {
            functionCallMap["A"] = std::bind(&reader::readA, this, std::placeholders::_1);
            functionCallMap["B"] = std::bind(&reader::readA, this, std::placeholders::_1);
            }

            void read()
            {
            const std::string table_name = "A";
            functionCallMap[table_name](table_name);
            }
            };

            int main()
            {
            reader r;
            r.read();
            }


            I pass the table name to the reader, it is nicely done with the bind and placeholder.






            share|improve this answer
























            • You should use string references in your callback functions instead of a copy. And as Moia said, you really should use a lambda instead of std::bind. About the aesthetics, I don't understand why you need a map of function since readA and readB are the same. Moreover readB is never used so why don't just put so code of readA into read?

              – Siliace
              Nov 18 '18 at 14:14













            • @Siliace, It seems lambda and bind has its own pros and cons, read A and read B are going to read different kinds of tables, different formats and invoke different factory methods down the line.

              – Ring Zero.
              Nov 18 '18 at 14:56














            1












            1








            1







            I ended up with this solution. It does the job, but I have some doubts over its aesthetics. Anyway, to sum up, I ended up with this code:



            #include <map>
            #include <iostream>
            #include <functional>
            class reader
            {
            std::map< std::string, std::function<void(std::string tableName)>> functionCallMap; // function pointer
            void readA(const std::string tableName){ std::cout << "reading:" << tableName<< "n"; }
            void readB(const std::string tableName){ std::cout << "reading:" << tableName <<"n"; }
            public:
            reader()
            {
            functionCallMap["A"] = std::bind(&reader::readA, this, std::placeholders::_1);
            functionCallMap["B"] = std::bind(&reader::readA, this, std::placeholders::_1);
            }

            void read()
            {
            const std::string table_name = "A";
            functionCallMap[table_name](table_name);
            }
            };

            int main()
            {
            reader r;
            r.read();
            }


            I pass the table name to the reader, it is nicely done with the bind and placeholder.






            share|improve this answer













            I ended up with this solution. It does the job, but I have some doubts over its aesthetics. Anyway, to sum up, I ended up with this code:



            #include <map>
            #include <iostream>
            #include <functional>
            class reader
            {
            std::map< std::string, std::function<void(std::string tableName)>> functionCallMap; // function pointer
            void readA(const std::string tableName){ std::cout << "reading:" << tableName<< "n"; }
            void readB(const std::string tableName){ std::cout << "reading:" << tableName <<"n"; }
            public:
            reader()
            {
            functionCallMap["A"] = std::bind(&reader::readA, this, std::placeholders::_1);
            functionCallMap["B"] = std::bind(&reader::readA, this, std::placeholders::_1);
            }

            void read()
            {
            const std::string table_name = "A";
            functionCallMap[table_name](table_name);
            }
            };

            int main()
            {
            reader r;
            r.read();
            }


            I pass the table name to the reader, it is nicely done with the bind and placeholder.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 17 '18 at 14:20









            Ring Zero.Ring Zero.

            12110




            12110













            • You should use string references in your callback functions instead of a copy. And as Moia said, you really should use a lambda instead of std::bind. About the aesthetics, I don't understand why you need a map of function since readA and readB are the same. Moreover readB is never used so why don't just put so code of readA into read?

              – Siliace
              Nov 18 '18 at 14:14













            • @Siliace, It seems lambda and bind has its own pros and cons, read A and read B are going to read different kinds of tables, different formats and invoke different factory methods down the line.

              – Ring Zero.
              Nov 18 '18 at 14:56



















            • You should use string references in your callback functions instead of a copy. And as Moia said, you really should use a lambda instead of std::bind. About the aesthetics, I don't understand why you need a map of function since readA and readB are the same. Moreover readB is never used so why don't just put so code of readA into read?

              – Siliace
              Nov 18 '18 at 14:14













            • @Siliace, It seems lambda and bind has its own pros and cons, read A and read B are going to read different kinds of tables, different formats and invoke different factory methods down the line.

              – Ring Zero.
              Nov 18 '18 at 14:56

















            You should use string references in your callback functions instead of a copy. And as Moia said, you really should use a lambda instead of std::bind. About the aesthetics, I don't understand why you need a map of function since readA and readB are the same. Moreover readB is never used so why don't just put so code of readA into read?

            – Siliace
            Nov 18 '18 at 14:14







            You should use string references in your callback functions instead of a copy. And as Moia said, you really should use a lambda instead of std::bind. About the aesthetics, I don't understand why you need a map of function since readA and readB are the same. Moreover readB is never used so why don't just put so code of readA into read?

            – Siliace
            Nov 18 '18 at 14:14















            @Siliace, It seems lambda and bind has its own pros and cons, read A and read B are going to read different kinds of tables, different formats and invoke different factory methods down the line.

            – Ring Zero.
            Nov 18 '18 at 14:56





            @Siliace, It seems lambda and bind has its own pros and cons, read A and read B are going to read different kinds of tables, different formats and invoke different factory methods down the line.

            – Ring Zero.
            Nov 18 '18 at 14:56


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53336880%2fhow-to-store-methods-as-function-pointers-in-a-map-container%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Bressuire

            Vorschmack

            Quarantine