注:この記事の末尾には、最小限の作業例があります。キーが見つからないときのQHashの理解
私はQt 5.7を使用しています。 QHash
次のは、私が持っているとしましょう:
QHash<HashKey, HashValue> hm;
enum HashKey {
K1,
K2,
K3,
K4,
K5
}
と
class HashValue {
public:
int x;
HashValue(int x) {
this->x = x;
}
}
で私はこのようなハッシュマップを初期化しています
hm.insert(K1, HashValue((int)K1));
hm.insert(K2, HashValue((int)K2));
hm.insert(K3, HashValue((int)K3));
hm.insert(K4, HashValue((int)K4));
hm.insert(K5, HashValue((int)K5));
私がテストしていますそれを呼び出すことによって
cout << hm.value(K4).x << endl;
cout << hm.find(K4).value().x << endl;
どちらも同じ結果が3
です。私が得たもの
cout << hm.value(static_cast<HashKey>(100)).x << endl;
cout << hm.find(static_cast<HashKey>(100)).value().x << endl;
が8
である(との最初の呼び出しのために:今、私はHashKey
の整数をキャストし、その上に上記の2つのメソッドを呼び出すことにより、ハッシュマップの一部ではないキーと同じことをやってみましたハッシュ内の指定されたキーにない項目、これら 関数RETがない場合value().x
)と5
は()find(...).value().x
と第2の呼のための
ドキュメントその
を述べurn a default-constructed value。
私はdefault-constructed value
のリンクをたどって、以下を得た:
)[...]例えば、QVectorが自動的 デフォルト-構築した値でその項目を初期化し、QMap ::値(指定されたキーがマップにない場合は、 デフォルト構築値を返します。ほとんどの値タイプが の場合、これは単に デフォルトコンストラクタ(たとえばQStringの空の文字列)を使用して値が作成されたことを意味します。しかし、 のintやdoubleやポインタ型のプリミティブ型の場合、 C++言語は初期化を指定しません。これらの例では、Qtの コンテナは自動的に、これは
HashValue()
コールを意味するであろう私の場合
値を0に初期化します。しかし、私が違う結果を出すという事実は、あまり言い表せないのです。無効なキーが引数として渡されたときに、find(...)
が何を言及していないとしても、私は同じ結果を得ることを期待しています。すべてそれは、そのキーの最初の出現を見つけ出し、イテレータを返すと言います(私が上記の呼び出しでそれにvalue()
を呼び出すので、明らかに)。
あなたは、ハッシュは、特定のキーが含まれているかどうかをチェック
)( が含まれている使用したい場合は、上から引用されたドキュメントスニペットは(再びQHash
のための文書へ)
が続いています
私はハッシュマップをクエリするたびにを呼び出す必要があります。これは2つの関数呼び出しを行うことを意味します。まず、キーが存在するかどうかを確認してから有効なエントリが見つかると
value(...)
を呼び出して呼び出します。以下の呼び出しは"Key 100 not found"
を返します。cout << (hm.contains(static_cast<HashKey>(100)) ? "Key 100 found" : "Key 100 not found") << endl;
私は、このチェックは内部で行われるが、明らかに、これは(私の推測では、このコンテナの照会機能にいくつかのパフォーマンスへの影響を防ぐことであろう)発生しません期待されます。
ここでの質問は、すべてこれが起こっており、実際には何が起こっているのでしょうか?ここで
は、プロジェクトとそのためのコードです:
HashTest.pro
QT += core QT += gui CONFIG += c++11 TARGET = HashTest CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += main.cpp
main.cppに
#include <QCoreApplication> #include <QHash> #include <iostream> using namespace std; enum HashKey { K1 = 0, K2 = 1, K3 = 2, K4 = 3, K5 = 4 }; class HashValue { public: int x; HashValue(int x) { this->x = x; } HashValue() {} }; int main(int argc, char *argv[]) { QHash<HashKey, HashValue> hm; hm.insert(K1, HashValue((int)K1)); hm.insert(K2, HashValue((int)K2)); hm.insert(K3, HashValue((int)K3)); hm.insert(K4, HashValue((int)K4)); hm.insert(K5, HashValue((int)K5)); cout << hm.value(K4).x << endl; cout << hm.value(static_cast<HashKey>(100)).x << endl; cout << hm.find(K4).value().x << endl; cout << hm.find(static_cast<HashKey>(100)).value().x << endl; cout << (hm.contains(static_cast<HashKey>(100)) ? "Key 100 found" : "Key 100 not found") << endl; return a.exec(); }
詳細な回答ありがとうございます。^_ ^私は私が得ていた異なった値のために未定義の振る舞いを考えました、そして、私はそれが本当に事実だったと思います。ですから、あなたが示した方法で 'contains()'や 'find()'を使います。 – rbaleksandar
@rbaleksandar値を使用したい場合はfindを使います。これで、一度「参照」するだけで済みます。 'contains'と' value'(またはfind)を使うと、2つのルックアップがあります。 – Hayt
これは私が恐れていたものでした。さて、それはfind()です。 :) – rbaleksandar