で指摘したようにはstd :: unique_ptrをするのstd :: unordered_setを使用して、それがポインタを見つけることは容易ではありませんT*
でしstd::unordered_set<std::unique_ptr<T>>
。C ++ 20より前は、のインスタンスを作成する必要がありましたstd::unique_ptr<T>
。
順序付けされていないコンテナの提案(http://wg21.link/P0919r3およびhttp://wg21.link/p1690r1)の異種ルックアップのおかげで、この問題はC ++ 20で解決されます。しかし、利用可能なソリューションは私にはかなり不器用に見えます(C ++標準でも)。1つではなく2つのファンクターを最初から実装する必要があるようです(透過的なハッシュと透過的な比較のため):
template<class T>
struct Equal {
using is_transparent = void;
bool operator()(const std::unique_ptr<T>& lhs, const std::unique_ptr<T>& rhs) const {
return lhs == rhs;
}
bool operator()(const std::unique_ptr<T>& lhs, const T* rhs) const {
return lhs.get() == rhs;
}
bool operator()(const T* lhs, const std::unique_ptr<T>& rhs) const {
return lhs == rhs.get();
}
};
template<class T>
struct Hash {
using is_transparent = void;
size_t operator()(const std::unique_ptr<T>& ptr) const {
return std::hash<const T*>()(ptr.get());
}
size_t operator()(const T* ptr) const {
return std::hash<const T*>()(ptr);
}
};
template<class T>
using UnorderedSetOfUniquePtrs = std::unordered_set<std::unique_ptr<T>, Hash<T>, Equal<T>>;
デモ:https://gcc.godbolt.org/z/bqx714(提案は現在MSVCでのみ実装されています)。
これは機能しますが、多くの定型文のように見えます。私は何かが足りないのですか?IDKを使用する方法はありますか?標準の透明なハッシャーまたは等価コンパレーターはありますか?私はそれが見std::equal_to<void>
透明ですが、私はそれを直接使用することはできません。unique_ptr<T> -> T*
「このUnorderedSetOfUniquePtrs
クラスのためだけに」暗黙の変換を定義する卑劣な方法があるのではないでしょうか。あなたのアイデアは大歓迎です。
冗長性をstd :: to_address(それを指摘してくれた@Calethに感謝)と、生のアドレスに基づいてハッシュを返すことにstd::hash
特化した既存のstd::unique_ptr
(ヒントをくれた@Mikhailに感謝)にシフトできます。次に、メンバー関数テンプレートを使用してハッシュ型と等価型を実装します(型自体をテンプレートにする必要がなくなったことに注意してください)。
struct Equal {
using is_transparent = void;
template<class U, class S>
bool operator()(const U& lhs, const S& rhs) const {
return std::to_address(lhs) == std::to_address(rhs);
}
};
struct Hash {
using is_transparent = void;
template<class U>
size_t operator()(const U& ptr) const {
return std::hash<U>{}();
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加