2

我正在尝试使用本地函数对成员变量类型 std::list 进行排序。由于 C++ 不允许本地函数,因此 Herb Sutter 建议使用本地类,因此我最终得到了以下代码。但我不确定如何将函数指针传递给std::list::sort()函数。

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

}

我收到编译器错误

模板参数不能引用本地类型

谢谢

4

2 回答 2

0

正如 juanchopanza 指出的那样,正如您在 c++11 中的这个问题中看到的那样,这个问题不再存在,所以如果可能的话,这可能是最好的方法。


如果不是,我想出了一个解决方案,如果你有少量类型的本地类(例如比较器,也许还有更多),你可能会很有用。我在前面提到的 SO 问题中举了一个例子,并对其进行了修改,使其可以在 C++03 下工作:


#include <iostream>
#include <vector>
#include <algorithm> // std::remove_if
using namespace std;

template <typename T>
class check {
public:
     virtual bool operator()(T x) = 0;
};

template <typename T>
struct cheat {
cheat(check<T> *c)  {_c = c;}
bool operator()(T x) {return _c->operator ()(x);}
check<T> *_c;
};

int main() {

int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<int> v( array, array+10 );

class even : public check<int>
{
     public:
     virtual bool operator()( int x ) { cout<<"Hi"<<endl; return !( x % 2 ); }
};
even e;

remove_if( v.begin(), v.end(),  cheat<int>(&e)); // no error, prints Hi

return 0;
}

同样在https://ideone.com/HY5bIU(用 Wall 编译,也很迂腐......)

例如,如果我想在我的代码中使用很多一元运算符,我可以创建一个抽象类,以便我的所有运算符都继承它,并且我创建了一个cheat基本上只用于帮助调用本地类的类.


编辑:另一个印记稍小的选项:

#include <iostream>
#include <vector>
#include <algorithm> // std::remove_if
using namespace std;

template <typename T>
class check {
public:
virtual bool operator()(T x) = 0;

     struct aid{
          aid(check *p){ _c = p;}
          check *_c;
          bool operator()(T x){
         return _c->operator ()(x);
     }
     };

     aid retMe(){
         return aid(this);
     }
};

int main() {

int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<int> v( array, array+10 );

class even : public check<int>
{
public:
         virtual bool operator()( int x ) { cout<<"Hi"<<endl; return !( x % 2 ); }
};
even e;

remove_if( v.begin(), v.end(), e.retMe()); // no error

return 0;
}

https://ideone.com/6SZ4UH


这里的aid类隐藏在抽象类本身内部,但是思路是一样的。

它确实添加了一些不必要的代码,但另一方面,它并不像某些 hack 那样怪诞。

于 2014-04-30T22:50:10.163 回答
0

显示运算符重载、静态函数(注释掉的调用)和 lambda 函数(注释掉的调用)的示例代码:

#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;
}
于 2014-05-01T01:17:42.193 回答