修复以下代码的最佳方法是什么:
#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
};
解决这个问题的一种方法是移动较少的定义&lt;至 namespace std(我知道,你不应该这样做。)
namespace std {
bool operator< ( area_t const& a, area_t const& b ) {
return( a->first < b->first );
};
};
另一个明显的解决方案是定义小于&lt;对于 对&LT; int,area_t&gt;但我想避免这样做 能够仅为一个元素定义运算符 没有定义的那对。
答案 0 :(得分:6)
当您实现一个实现某种特定和/或相当奇特的比较方法的比较器时,最好使用命名函数或函数对象,而不是为此目的劫持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
成员。但这可能不会让人感觉到,因为你的比较是“充满异国情调”的。