2016-05-26 34 views
3

我有一個類Parent,它從文件加載配置數據並在std::map中創建Child對象。 Child對象由配置文件中定義的const char*進行映射。對於任何給定Parent,所有孩子將共享相同的密鑰長度。因此,一個Parent的映射Child對象可能有8個字節的密鑰,另一個Parent的孩子可能會使用4個字節的密鑰。與memcmp比較的STL映射。如何在運行時設置比較塊大小?

如何使用方法described here或使用其他方法創建新的std::map成員對象,該對象的比較函數依賴於僅在運行時可用的數據?

具體來說,我試圖用memcmp(a, b, n);像以前鏈接的問題表明,但我想n是可變的,而不是固定在4

如果我沒有解釋不夠好,我嘗試要做的,我會嘗試把它放在代碼中。我怎樣寫的compareKey,以便它使用childKeyLength比較映射鍵:如果你的鑰匙其實只是任意的二進制數據,你的意見建議,那麼也許你真正想要的是

class Child; 
class Parent { 
private: 
    struct compareKey { 
     bool operator()(char * const a, char * const b) { 
      return memcmp(a, b, childKeyLength) < 0; 
     } 
    }; 
    std::map<const char*, Child, compareKey> children; 
    size_t childKeyLength; 

public: 
    Parent(size_t childKeyLength) 
    : childKeyLength(childKeyLength) {}; 
} 
+2

爲什麼不使用'strcmp'? –

+0

處理不一定以null結尾的二進制數據。 –

+0

爲什麼首先使用'char *'?爲什麼不'std :: string'或'std :: vector'? –

回答

5

std::map<std::vector<char>, Child> children; 

vector已經有一個operator<,它實現了嚴格的弱排序,所以這只是起作用。


如果別的東西擁有數據,那麼我建議包裝長度入式和比較的是:

struct Data { 
    const char* p; 
    size_t len; 
}; 

struct DataComparer { 
    bool operator()(Data const& lhs, Data const& rhs) const { 
     int cmp = memcmp(lhs.p, rhs.p, std::min(lhs.len, rhs.len)); 
     return cmp < 0 || cmp == 0 && lhs.len < rhs.len; 

     // or if you're feeling feisty? 
     // return std::make_tuple(memcmp(lhs.p, rhs.p, std::min(lhs.len, rhs.len)), lhs.len) 
     //  < std::make_tuple(0, rhs.len); 
    } 
}; 

std::map<Data, Child, DataComparer> children; 

如果密鑰長度固定,那麼你可以簡單地將它作爲比較對象的成員(而不是它只是在某處浮動):

struct MemComparer { 
    size_t length; 

    bool operator()(const char* lhs, const char* rhs) const { 
     return memcmp(lhs, rhs, length) < 0; 
    } 
}; 

現在map可以合理的方式複製 - 您只需要通過map構造函數MemComparer實例。

+0

我就會想到你建議的包裝方法。在那種情況下,重載'operator <'會更好嗎? –

+0

@JoshuaB。在什麼上重載'operator <'? – Barry

+0

'運營商<'數據' –