(私の前の質問に関連)
QT では、QMap
ドキュメントには次のように記載されています。
QMap のキー タイプは、合計順序
operator<()
を指定する必要があります。
ただし、 では、ポインターを比較するqmap.h
ために次のようなものを使用しているようです。std::less
/*
QMap uses qMapLessThanKey() to compare keys. The default
implementation uses operator<(). For pointer types,
qMapLessThanKey() casts the pointers to integers before it
compares them, because operator<() is undefined on pointers
that come from different memory blocks. (In practice, this
is only a problem when running a program such as
BoundsChecker.)
*/
template <class Key> inline bool qMapLessThanKey(const Key &key1, const Key &key2)
{
return key1 < key2;
}
template <class Ptr> inline bool qMapLessThanKey(const Ptr *key1, const Ptr *key2)
{
Q_STATIC_ASSERT(sizeof(quintptr) == sizeof(const Ptr *));
return quintptr(key1) < quintptr(key2);
}
quintptr
ポインターをs (の QT バージョンuintptr_t
、つまり、ポインターを格納できる unsigned int )にキャストし、結果を比較するだけです。
次の型は、void への任意の有効なポインターをこの型に変換し、その後 void へのポインターに戻すことができるプロパティを持つ符号なし整数型を指定します。結果は元のポインターと等しくなります。
uintptr_t
qMapLessThanKey()
このon ポインターの実装は問題ないと思いますか?
もちろん、整数型には完全な順序があります。しかし、これは、この操作がポインターの全体的な順序を定義していると結論付けるのに十分ではないと思います。
AFAIKが指定されていないことをp1 == p2
意味する場合にのみ、それは真実だと思います。quintptr(p1) == quintptr(p2)
この状態の反例として、ポインターに 40 ビットを使用するターゲットを想像してください。ポインターを に変換しquintptr
、最下位 40 ビットをポインター アドレスに設定し、最上位 24 ビットを変更せずに (ランダムに) 残すことができます。これは と ポインター間の変換可能性を尊重するのに十分ですquintptr
が、これはポインターの全体的な順序を定義しません。
どう思いますか?