6

修复以下代码的最优雅方法是什么:

#include <vector>
#include <map>
#include <set>
using namespace std;

typedef map< int, int > row_t;
typedef vector< row_t > board_t;
typedef row_t::iterator area_t;

bool operator< ( area_t const& a, area_t const& b ) {
    return( a->first < b->first );
};

int main( int argc, char* argv[] )
{
    int row_num;
    area_t it;

    set< pair< int, area_t > > queue;
    queue.insert( make_pair( row_num, it ) ); // does not compile
};

解决它的一种方法是将 less< 的定义移动到命名空间 std (我知道,  你不应该这样做。

namespace std {
    bool operator< ( area_t const& a, area_t const& b ) {
        return( a->first < b->first );
    };
};

另一个明显的解决方案是为 pair< int, area_t > 定义小于<,但我想避免这种情况,并且只能为未定义的对中的一个元素定义运算符。

4

1 回答 1

7

当您实现一个比较器来实现一些特定和/或相当奇特的比较方法时,最好使用命名函数或函数对象,而不是operator <为此目的劫持。我想说比较std::pair对象的自然方法是使用字典比较。由于您的比较不是按字典顺序进行的,因此接管operator <可能不是一个好主意。更好地实现一个比较器类

typedef pair< int, area_t > Pair; // give it a more meaningful name

struct CompareFirstThroughSecond {
  bool operator ()(const Pair& p1, const Pair& p2) const { 
    if (p1.first != p2.first) return p1.first < p2.first;
    return p1.second->first < p2.second->first;
  }
};

并将其与您的容器一起使用

std::set< Pair, CompareFirstThroughSecond > queue;  

(我希望我从您的原始代码中正确解读了您的意图)。

您还可以将上述operator ()方法实现为模板方法,从而使其可用于所有std::pair基于迭代器的类型作为second成员。不过,这可能没有意义,因为您的比较足够“异国情调”。

于 2010-02-24T19:50:52.407 回答