2012-05-01 8 views
9

背景:私はJavaの世界から来ており、C++やQtを新しく使っています。ベクタをキーとして使用するとC++のunordered_mapが失敗する

#include <QtCore/QCoreApplication> 
#include <QtCore> 
#include <iostream> 
#include <stdio.h> 
#include <string> 
#include <unordered_map> 

using std::string; 
using std::cout; 
using std::endl; 
typedef std::vector<float> floatVector; 

int main(int argc, char *argv[]) { 
    QCoreApplication a(argc, argv); 

    floatVector c(10); 
    floatVector b(10); 

    for (int i = 0; i < 10; i++) { 
     c[i] = i + 1; 
     b[i] = i * 2; 
    } 

    std::unordered_map<floatVector, int> map; 

    map[b] = 135; 
    map[c] = 40; 
    map[c] = 32; 

    std::cout << "b -> " << map[b] << std::endl; 
    std::cout << "c -> " << map[c] << std::endl; 
    std::cout << "Contains? -> " << map.size() << std::endl; 

    return a.exec(); 
} 

は、残念ながら、私は感動ではないfolowingエラーに実行しています:unordered_mapと遊ぶために

は、私は次の簡単なプログラムを書かれています。行番号さえありません。

:-1: error: collect2: ld returned 1 exit status

問題の原因は何ですか?

ありがとうございます。

+1

「ベクトル」を受け取るハッシュ関数が必要です –

+2

これは実行時エラーではありません。 –

+0

@SethCarnegieそれは私の問題でもありました。しかし、ベーシックなクラスはデフォルトのハッシュ関数を持っているはずです。それが事実でない場合、あなたは私に何かを提供する方法を教えてくれますか、何かを教えてください。ありがとうございました! –

答えて

21

§23.2.5、第3項は、こう述べています。

Each unordered associative container is parameterized by Key , by a function object type Hash that meets the Hash requirements (17.6.3.4) and acts as a hash function for argument values of type Key , and by a binary predicate Pred that induces an equivalence relation on values of type Key .

Keyとしてvector<float>を使用して明示的なハッシュと同値述語の種類を提供していないことを意味デフォルトstd::hash<vector<float>>をしてstd::equal_to<vector<float>>が使用されます。

ベクトルの演算子==が存在するため、等価関係のためのstd::equal_toはうまくいきます。それはstd::equal_toのものです。

ただし、std::hash<vector<float>>の特殊化はありません。これはおそらく、あなたが私たちに示されていないリンカのエラーと言います。これを行うには、独自のハッシャーを用意する必要があります。

な調理人の書き込みが簡単な方法はboost::hash_rangeを使用することです:

template <typename Container> // we can make this generic for any container [1] 
struct container_hash { 
    std::size_t operator()(Container const& c) const { 
     return boost::hash_range(c.begin(), c.end()); 
    } 
}; 

次にあなたが使用することができます。もちろん

std::unordered_map<floatVector, int, container_hash<floaVector>> map; 

を、あなたが必要とするマップで異なる平等のセマンティクスが必要な場合ハッシュと等価関係を適切に定義する。


しかしながら、異なる順序が異なるハッシュが生成されますよう、順不同コンテナをハッシュするためにこれを回避し、かつ順不同コンテナ内の順序は保証されません。

+1

これは本当にありがとう、私の問題を解決しました。 同じ問題を抱える人への注意: boost :: hash_rangeを使用するには#include

+0

@ user1162647:これは文字通りそのドキュメントページの最初のものです。 ; - ] – ildjarn

+0

@R。Martinho Fernandes:あなたがまだ見ているなら、そのページのドキュメントはこう言っています: "hash_rangeは要素の順序に敏感なので、これを順序付けられていないコンテナで使用することは適切ではありません。"上記の使用法が間違っていることを示唆していますか? – ForeverLearning

関連する問題