C ++ service providers

I am learning C ++ coming from C # where I am used to using service providers: basically a dictionary <Type, object>. Unfortunately, I can't figure out how to do this in C ++. So the questions are basically:

  • How to make a dictionary in C ++.

  • How I would use "Type" with it, as far as I know there is no "Type" in C ++.

  • Same as above, but with "object".

Thank!

+1


source to share


4 answers


I am assuming you are trying to map a type to an instance of one object. You can try something along these lines:

#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>();
}

      



In C ++, types are not first-class objects of their own, but at least the type name will be unique, so you can use that.

Edit: The names are not actually guaranteed to be unique, so hold on to the type_info pointers and use the before method to compare them.

+5


source


You probably want to look at the STL map template . C ++, of course, has types (it's hard to have inheritance without it), it just doesn't have a specific "Type" class defined.



+3


source


STL has two associative containers: std::map<K,V> and

std :: multimap. There is also std::set<V>

, which should be an adapter std::map<V,void>

, but as such it is not an associative container. Multimap is similar to a map, only it allows you to use several identical keys in one container. Both cards and multibrand hold type elements std::pair<K,V>

. In other words std::map<K,V>::value_type == std::pair<K,V>

, but std::map<K,V>::key_type == K

also std::map<K,V>::mapped_type == V

.

As for "Type", I'm not really sure what you mean. If you mean parameterized classes, then C ++ calls this "Template Programming" or "General Programming". In the example above, the parameter is std::map<K,V>

parameterized over K and V for key type and value type. C ++ also supports template functions:

template<typename T>
void f(T o);

      

will declare a function that accepts any type at all, including primitive types, as a parameter. C ++ does not support generic type resolution, so the type T must have a specific hierarchy. For now, all you can do is just assume that the passed type does indeed match the correct hierarchy, and the compiler will complain if you try to call an undeclared function on an object of that type.

template<typename T>
void f(T o) {
    o.do_it();
}

      

The above will work as long as T defines a method do_it()

.

+2


source


Dictionary sounds like STL map for me std::map<K, T>

. Take a look at the standard template library - it's brilliant. It has been part of ANSI C ++ for a while. If I recall correctly, Microsoft has a good implementation from PJ Plauger.

0


source







All Articles