質問
私は C# から C++ を学習しており、サービス プロバイダーの使用に慣れてきました。基本的には Dictionary<Type, object> です。残念ながら、C++ でこれを行う方法がわかりません。したがって、質問は基本的に次のとおりです。
C++ で辞書を作成するにはどうすればよいでしょうか。
私の知る限り、C++ には「Type」がありません。
上記と同じですが、「オブジェクト」を使用します。
ありがとう!
解決
タイプを単一のオブジェクトインスタンスにマップしようとしていると仮定しています。これらの線に沿って何かを試すことができます:
#include <typeinfo>
#include <map>
#include <string>
using namespace std;
class SomeClass
{
public:
virtual ~SomeClass() {} // virtual function to get a v-table
};
struct type_info_less
{
bool operator() (const std::type_info* lhs, const std::type_info* rhs) const
{
return lhs->before(*rhs) != 0;
}
};
class TypeMap
{
typedef map <type_info *, void *, type_info_less> TypenameToObject;
TypenameToObject ObjectMap;
public:
template <typename T>
T *Get () const
{
TypenameToObject::const_iterator iType = ObjectMap.find(&typeid(T));
if (iType == ObjectMap.end())
return NULL;
return reinterpret_cast<T *>(iType->second);
}
template <typename T>
void Set(T *value)
{
ObjectMap[&typeid(T)] = reinterpret_cast<void *>(value);
}
};
int main()
{
TypeMap Services;
Services.Set<SomeClass>(new SomeClass());
SomeClass *x = Services.Get<SomeClass>();
}
C ++では、型はそれ自体がファーストクラスのオブジェクトではありませんが、少なくとも型名は一意になるため、それによってキーを設定できます。
編集:名前は実際には一意であることが保証されていないため、type_infoポインターを保持し、beforeメソッドを使用してそれらを比較します。
他のヒント
STLマップテンプレートをご覧ください。 C ++には確かに型があり(継承せずに継承するのは難しい)、特定の<!> quot; Type <!> quot;クラス。
STL には 2 つの連想コンテナがあります。 std::map<K,V> and
std::マルチマップ。もあります std::set<V>
これはアダプターである必要があります std::map<V,void>
, ですが、それ自体は連想コンテナではありません。マルチマップはマップと似ていますが、同じコンテナ内で複数の同一キーを許可する点が異なります。マップとマルチマップはどちらも次のタイプの要素を保持します。 std::pair<K,V>
. 。言い換えると、 std::map<K,V>::value_type == std::pair<K,V>
, 、 しかし std::map<K,V>::key_type == K
そして std::map<K,V>::mapped_type == V
.
「タイプ」については、何を言っているのかよくわかりません。パラメーター化されたクラスを意味する場合、C++ ではこれを「テンプレート プログラミング」または「ジェネリック プログラミング」と呼びます。上記では、 std::map<K,V>
は、キーのタイプと値のタイプについて K および V でパラメータ化されます。C++ はテンプレート関数もサポートしています。
template<typename T>
void f(T o);
プリミティブ型を含む任意の型をパラメータとして受け取る関数を宣言します。C++ は、型 T が特定の階層でなければならないなど、ジェネリック型の解決をサポートしていません。現時点では、渡された型が実際に正しい階層のものであると仮定することしかできません。その型のオブジェクトに対して宣言されていない関数を呼び出そうとすると、コンパイラはエラーを出します。
template<typename T>
void f(T o) {
o.do_it();
}
T がメソッドを定義している限り、上記は機能します。 do_it()
.
辞書は、STLマップのように聞こえます:std::map<K, T>
。標準テンプレートライブラリをご覧ください-それは素晴らしいです。しばらくの間、ANSI C ++の一部でした。正しく思い出せば、MicrosoftにはPJ Plaugerからの素晴らしい実装があります。