2010-02-24 25 views
6

什麼是太修復下面的代碼最優雅的方式:解決它是動得少<到 空間std的定義(提供小於運算符一對中的一個元素

#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 
}; 

的一種方式我知道,    你不應該這樣做。

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

另一個明顯的解決方案是小於<爲定義pair < int,area_t>但我想避免這種情況,並且 能夠定義運算符僅限於未定義的對的一個元素 。

+4

這是一個有趣的名字,你在那裏設置;) – 2010-02-24 19:56:18

+0

什麼是名字?任何其他名字的玫瑰都會聞到甜味。 – 2010-02-24 22:23:44

回答

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成員。雖然它可能沒有意義,因爲你的比較足夠「異國情調」了。

+1

你似乎錯過了'std :: pair'已經實現了'operator <',並且OP想知道如何插入第二個成員(迭代器)的比較器。 – UncleBens 2010-02-24 20:32:27

+0

@UncleBens:哦,明白了。你是對的。不過,我提議應該工作。另外,試圖通過運算符重載實現一個用於迭代器類型的比較器是一個冒險的嘗試,因爲在一般情況下,迭代器可能碰巧是由內置類型實現的(運算符重載是不可能的)。 – AnT 2010-02-24 20:35:02

+1

@UncleBens - 這是一個很好的方式。我想爲該對的第二個元素插入一個運算符。 @AndreyT - 我需要首先比較對中的整數,如果它們相等,則繼續比較對中的area_t成員。這將工作。 但是,這正是我試圖避免的解決方案 - 已爲'std :: pair'和ints實現'operator <'。我不想重新發明輪子。 (另外這是一個非常多的輸入。) – 2010-02-24 22:37:27

相關問題