c++stdlistlocal-class

passing local class function pointer to std::list::sort


I am trying to sort a member variable type std::list using a local function. Since C++ doesn't allow local functions and hence Herb Sutter's suggests local classes, I ended up with the following code. But am not sure how I can pass a function pointer to the std::list::sort() function.

void MyClass::UpdateList()
  std::map<ClassA*, int> myCustomOrder; //contains order for ClassA objects
  class CompareMyClass
  {
  public:
    CompareMyClass(std::map<ClassA*, int>* order) : m_order(order) { }
    bool operator()(ClassA *p1, ClassA *p2) {
      return m_order->find(p1) < m_order->find(p2);
      return false;
    }
  private:
    std::map<ClassA*, int>* m_order;
  };

  CompareMyClass compareObj(&myCustomOrder); // set the order
  // sort the list
  m_list.sort(compareObj); // How do I pass a function pointer at this point

}

I get a compiler error

a template argument may not reference a local type

Thanks


Solution

  • Example code showing operator overloading, a static function (call commented out), and a lambda function (call commented out):

    #include <iostream>
    #include <list>
    #include <string>
    
    class names
    {
        struct name_node
        {
            std::string name;
            inline bool operator< (const name_node &rnode)
                {return (this->name < rnode.name);}
            static bool compare_node(const name_node & lnode, const name_node & rnode)
                {return (lnode.name < rnode.name);}
        };
    
        std::list <name_node> name_list;
    
    public:
        void get_data();
        void sort_data();
        void show_data();
    };
    
    void names::get_data()
    {
    name_node nn;
    std::string fruits[5] = { "peach", "cherry", "apple", "plum", "banana" };
    
        for (size_t i = 0; i < sizeof(fruits) / sizeof(fruits[0]); i++){
            nn.name = fruits[i];
            name_list.push_back(nn);
        }
    }     
    
    void names::sort_data()
    {
        name_list.sort();
    //  name_list.sort(names::name_node::compare_node);
    //  name_list.sort([this](const name_node & lnode, const name_node & rnode)
    //                  {return (lnode.name < rnode.name);});
    }
    
    void names::show_data()
    {
    std::list<name_node>::iterator it;
        for(it = name_list.begin(); it != name_list.end(); ++it)
            std::cout << (*it).name << std::endl;
    };
    
    int main()
    {
    names n;
        n.get_data();
        n.sort_data();
        n.show_data();
        return 0;
    }