私は C# から来て C++ を学んでおり、そこではサービス プロバイダー (基本的には Dictionary<Type, object>) の使用に慣れてきました。残念ながら、C++ でこれを行う方法がわかりません。したがって、質問は基本的に次のとおりです。
C++ で辞書を作成する方法を教えてください。
C++に「タイプ」がないことを知っている限り、「タイプ」をどのように使用しますか。
上記と同じですが、「オブジェクト」を使用します。
ありがとう!
私は C# から来て C++ を学んでおり、そこではサービス プロバイダー (基本的には Dictionary<Type, object>) の使用に慣れてきました。残念ながら、C++ でこれを行う方法がわかりません。したがって、質問は基本的に次のとおりです。
C++ で辞書を作成する方法を教えてください。
C++に「タイプ」がないことを知っている限り、「タイプ」をどのように使用しますか。
上記と同じですが、「オブジェクト」を使用します。
ありがとう!
タイプを単一のオブジェクトインスタンスにマップしようとしていると仮定しています。次の行に沿って何かを試すことができます。
#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++には確かに型があり(それなしでは継承が難しい)、特定の定義された「型」クラスはありません。
STL には、 std::map<K,V> and
std::multimap という 2 つの連想コンテナーがあります。std::set<V>
のアダプターであるべきものもありますが、それ自体std::map<V,void>
は連想コンテナーではありません。multimap は map に似ていますが、同じコンテナー内で複数の同一のキーを許可する点だけが異なります。map と multimap はどちらも type の要素を保持します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 が method を定義している限り機能しますdo_it()
。
辞書は、私には STL マップのように聞こえます: std::map<K, T>
. Standard Template Library をご覧ください。素晴らしいです。しばらくの間、ANSI C++ の一部でした。私の記憶が正しければ、Microsoft は PJ Plauger による優れた実装を提供しています。