23

背景: 私は Java の世界から来ており、C++ や Qt にはかなり慣れていません。

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();
}

残念ながら、刺激的ではない次のエラーが発生しています。行番号すらありません。

:-1: エラー: collect2: ld が 1 つの終了ステータスを返しました

問題の原因について何か考えはありますか?

4

2 に答える 2

36

§23.2.5、パラグラフ 3 は次のように述べています。

各順序付けられていない連想コンテナは、 、ハッシュ要件 (17.6.3.4) を満たし、 type の引数値のハッシュ関数としてKey機能する関数オブジェクト型、および typeの値に等価関係を誘導するバイナリ述語によってパラメーター化されます。HashKeyPredKey

vector<float>asを使用しKey、明示的なハッシュおよび等価述語タイプを提供しないことは、デフォルトstd::hash<vector<float>>を意味し、std::equal_to<vector<float>>使用されます。

ベクトルstd::equal_toの演算子があり、それが使用されるため、同値関係の for は問題ありません。==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. ただし、順序が異なると異なるハッシュが生成され、順序なしコンテナの順序は保証されないため、順序なしコンテナのハッシュではこれを避けてください。

于 2012-05-01T22:13:25.297 に答える