【问题标题】:Using `std::sort` with a member function in a templated class在模板类中使用带有成员函数的`std::sort`
【发布时间】:2012-06-04 18:00:26
【问题描述】:

我遇到的问题是我想在模板类中使用 STL 的排序和自定义比较函数。

使用 typedef 的想法来自另一个Stackoverflow Post

不管怎样,代码如下:

template <typename R,typename S>
class mesh{
  /* some stuff */

  void sortData(){
    typedef bool (*comparer_t)(const S,const S);
    comparer_t cmp = &mesh::compareEdgesFromIndex;
    sort(indx,indx+sides*eSize,cmp);
  }

  /* more stuff */

  // eData and cIndx are member variables
  bool compareEdgesFromIndex(const S a,const S b){
    return compareEdges(eData[cIndx[2*a]],eData[cIndx[2*a+1]],eData[cIndx[2*b]],eData[cIndx[2*b+1]]); 
  }
};

我得到的错误是

mesh.h:130:29: error: cannot convert ‘bool (mesh<float, unsigned int>::*)(unsigned int, unsigned int)’ to ‘comparer_t {aka\
bool (*)(unsigned int, unsigned int)}’ in initialization

提前谢谢你!

【问题讨论】:

    标签: c++ class templates function-pointers typedef


    【解决方案1】:

    您正在尝试在需要 function-pointer 的地方混合 member-function-pointer。您可以将谓词重构为 static 函数,或使用 bindings 将您的 member-function-pointer 与您的类 mesh 的实例相关联。

    为了将一个实例绑定到你的 member-function-pointer 你应该这样做

    std::bind( mesh_instance, &mesh::compareEdgesFromIndex, _1, _2 )
    

    如果使用 C++11。如果您没有奢侈,那么您可以使用 Boost 中的等效功能(将 std::bind 替换为 boost::bind)。 C++03 提供了一些绑定功能,但功能有限,我相信现在已过时通用绑定功能可用。

    【讨论】:

    • 对不起,作为一个新手,第二个选项将如何实现?谢谢!
    【解决方案2】:

    您必须将compareEdgesFromIndex 声明为静态:

    static bool compareEdgesFromIndex(const S a,const S b){
      return compareEdges(eData[cIndx[2*a]],eData[cIndx[2*a+1]],eData[cIndx[2*b]],eData[cIndx[2*b+1]]); 
    }
    

    假设compareEdges 也是静态的。否则,您有一个成员函数指针,需要调用 mesh 指针。

    【讨论】:

    • 感谢您的回复!将两者都声明为静态时,我收到一条错误消息,指出 eData 和 cIndx 的使用无效
    • 您应该了解什么是静态成员函数。您显然必须修改您的代码,使其不依赖于实例变量,因为您的方法将是静态的(这意味着它在某种程度上是一个“全局函数”)。我的回答只是修复了您的错误消息:D.
    • 感谢您的澄清
    【解决方案3】:

    或者,如果您希望使用 compareEdgesFromIndex 作为非静态成员函数,您可以将 boost::bind(this, &amp;mesh::compareEdgesFromIndex, _1, _2) 作为比较器传递。

    【讨论】:

    • 我没有boost库,但我会试试。谢谢你的回复!
    • 不客气。你可以在 boost.org 上找到 boost 库。它的跨平台和预构建包可用于各种操作系统。
    【解决方案4】:

    成员函数不是函数,因为要工作,它还需要知道正在作用的对象实例是哪个。 static 成员基本上只是一个普通的全局函数,具有一个有趣的名称和访问类私有部分的权限。

    确实,指向非静态成员函数的指针不是你可以简单调用的东西,而是你可以提供一个对象实例来获取你可以调用的东西的东西。

    您可以改为传递std::sort 一个类的对象实例,该类实现::operator()(int, int),给定两个索引将返回所需的结果。不幸的是,由于我在 C++ 中从未理解过的原因,这个对象类必须是非本地类,因为本地类不能在模板中使用(它可以是在另一个类中定义的类,但不是在函数或方法中定义的类)。

    【讨论】:

    • 感谢您的解释!
    【解决方案5】:

    作为std::bind 的替代方案,您可以使用我更喜欢的lambda,因为我永远记不起std::bind 的语法。

    auto cmp = [&mesh_instance](unsigned lhs, unsigned rhs) {
        return mesh_instance.compareEdgesFromIndex(lhs, rhs);
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-24
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 2015-05-03
      相关资源
      最近更新 更多