タイプ消去を使用してマップ ラッパーを実装するライブラリを C++ で作成しています。ラッパーは、このすばらしい記事のように構成されています: http://www.cplusplus.com/forum/articles/18756/。
TLDR:
template<typename K, typename V>
class AnyMap
{
class MapConcept
{
public:
// Lots of pure virtual methods...
// These mimic the intersection of STL and Boost maps' interfaces
// Example:
virtual size_type size() = 0;
};
template<typename ActualMapType>
class MapModel : MapConcept
{
ActualMapType m;
public:
// Implementations of the parent's virtual methods...
// These basically just call the same method on member m.
// Example:
size_type size() { return m.size(); }
};
MapConcept* mapConcept;
public:
// Again, the STL and Boost maps' interface methods
// Example:
size_type size() { return mapConcept->size(); }
};
このマップを完成したライブラリの一部として公開するか、ヘルパー クラスとして隠すかはわかりませんが、どちらにしても、代入演算子をどうするかは考え中です。
現在、私は次のようなものを持っています:
AnyMap& AnyMap::operator=(const AnyMap& other) {
delete mapConcept;
mapConcept = other.mapConcept->clone();
return *this;
}
これは、たとえば STL のマップと Boost の unordered_map を使用して 2 つのマップを作成し、一方を他方に割り当てると、両方の基になるマップ タイプが同じになることを意味します。
std::map<string, int> stlMap;
boost::unordered_map<string, int> boostMap;
// insert some stuff into maps
AnyMap<string, int> stlAnyMap( stlMap );
AnyMap<string, int> boostAnyMap( boostMap );
stlAnyMap = boostAnyMap;
// now stlAnyMap has a copy of boostMap
に割り当てられたマップの内容が期待どおりであるため、これはある程度理にかなっています。ただし、通常、マップ タイプは、デフォルト値を持つタイプ引数の 1 つ (Boost::unordered_map の Hash など) によって異なると思われます。したがって、基になるマップ タイプを保持する必要があるかもしれません。私は、これは次のようなもので行うことができると思います:
AnyMap& AnyMap::operator=(const AnyMap& other) {
mapConcept->clear();
mapConcept->insert( other.mapConcept->begin(), other.mapConcept->end() );
return *this;
}
テンプレート化された挿入メソッドにより、これは機能するはずです。
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
ところで、私がイテレータをどのように扱ったか疑問に思っている人がいれば、私は Thomas Becker の any_iterator - http://thbecker.net/free_software_utilities/type_erasure_for_cpp_iterators/any_iterator.htmlを使用しました。
それで、あなたたちはどう思いますか?私は後者のアプローチに傾いていますが、どちらの側の議論も聞きたいです。
前もって感謝します!
編集: ここに反対の最初の引数があります (おそらく、これがどれほど重要か教えてください): 1 つの述語がマップ内の 2 つのキーを区別し、もう一方の述語がマップ内の 2 つのキーを区別する場合、1 つのマップ タイプの内容が別のマップに 1 対 1 でマップされる可能性があります。はそれらを同じと見なします。