5

我有问题要问。

我创建了一个名为 AstarPlanlama 的类,并具有以下两个功能:

bool AstarPlanlama::nodeComp(const Node* lhs, const Node* rhs) 
{
   return lhs->F < rhs->F;
}

void AstarPlanlama::enKucukFliNodeBul(std::list<Node*> * OPEN)
{
    std::list<Node*>::iterator it = std::min_element(OPEN->begin(), OPEN->end(), &AstarPlanlama::nodeComp);

    OPEN->sort(&AstarPlanlama::nodeComp);   

    Q = OPEN->front();      

    OPEN->pop_front();      
}

当我编译我的代码时,错误发生在xutility.h文件中。

template<class _Pr, class _Ty1, class _Ty2> inline
    bool _Debug_lt_pred(_Pr _Pred,
        _Ty1& _Left, _Ty2& _Right,
        _Dbfile_t _File, _Dbline_t _Line)
    {   // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
    if (!_Pred(_Left, _Right))
        return (false);
    else if (_Pred(_Right, _Left))
        _DEBUG_ERROR2("invalid operator<", _File, _Line);
    return (true);
    }

函数声明:

    bool nodeComp(const Node* lhs, const Node* rhs);

    void enKucukFliNodeBul(std::list<Node*> * OPEN);

错误行是if (!_Pred(_Left, _Right))

代码有什么问题?

谢谢你的回报。。

致以我的问候..

4

2 回答 2

4

看起来您正在传递一个成员函数作为您的自定义比较器。制作static或使用std::bind

 std::list<Node*>::iterator it = std::min_element(OPEN->begin(), OPEN->end(),
                                       std::bind(&AstarPlanlama::nodeComp, 
                                                 this,
                                                 std::placeholders::_1,
                                                 std::placeholders::_2));

OPEN->sort(std::bind(&AstarPlanlama::nodeComp, 
                     this,
                     std::placeholders::_1,
                     std::placeholders::_2));

成员函数很特殊,需要在对象上调用,这就是为什么std::bind需要绑定到this指针的原因。

于 2012-12-17T22:13:17.223 回答
2

您的声明nodeComp()是错误的 - 如果您想遵循标准库约定,它需要是自由函数或静态函数,而不是常规成员函数。通常,我建议将其设置为标记为朋友的免费功能,以便它可以访问私有类成员。您声明的函数不会生成 xutility.h 中预期的比较器函数,因为它带有“隐藏的 this”参数,该参数由所有非静态成员函数携带。

此外,鉴于 的实现nodeComp(),根本没有理由将其设为常规成员函数,因为它不对其对象的数据进行操作,而是对作为参数传入的对象的数据进行操作。

为了简化您的生活和其他必须维护代码的人的生活,我将遵循标准库约定并将 nodeComp() 替换为以下代码,并在 AstarPlanlama 的类声明中声明操作员为朋友。

bool operator<(const AstarPlanlama::Node* lhs, const AstarPlanlama::Node* rhs) 
{
  return lhs->F < rhs->F;
}

此外,将原始指针放入标准库容器通常不是一个好主意,因为这会导致各种有趣的生命周期管理问题。如果您绝对必须使用指针,我建议您使用为它设计的容器,例如 boost 指针容器,或者将对象包装在 a 中std::shared_ptr而不是处理原始指针。

于 2012-12-17T22:13:42.230 回答