Hi all,

I'm trying to figure out how to do this:

A "manager" containing a list of "providers" which each contain a list of "assets". The assets can be inherited to create different types of assets (ie. audio, video, script, etc.). Ideally the interface should be with the derived types, not the base interface (ie. derived class AudioAsset, not base interface Asset), which implies use of templates and/or casting. This should mean that the list of providers is not providers holding pointers to the base interface (like I've done below), but instead the derived types. Which confuses me because I don't know how the manager can hold a list of providers who each hold different lists of assets.

In addition to all that, I don't know how, when calling GetAsset<AssetTypeHere> on the manager to choose the provider associated with AssetTypeHere. I think that could be solved by adding a static name = "audio", or "video", etc. and using a hash table. Since we can't rely on object reflection in C++ (I read).

So basically I just need to figure out how Manager could store AudioAssetProvider's and VideoAssetProvider's, etc. without hardcoding all the provider types beforehand of course (ie. list for each provider - ew). This would allow me to remove the static_cast.

This example works, just to go along with the explanation.

Code:
#include <iostream>
#include <map>
#include <string>
#include <vector>

class Asset
{
public:
    std::string name;
};

class AudioAsset : public Asset
{
public:
    AudioAsset() { this->name = "audio audio audio"; }
};

template <typename T>
class Provider
{
public:
    void AddAsset(std::string name, T& asset)
    {
        this->list.insert(std::pair<std::string, T>(name, asset));
    }

    T& GetAsset(std::string& name)
    {
        return this->list.find(name)->second;
    }

    bool AssetExists(std::string& name)
    {
        if(this->list.find(name) != this->list.end())
            return true;
        else
            return false;
    }

private:
    std::map<std::string, T> list;
};

typedef Provider<Asset*> AssetProvider;

typedef Provider<AudioAsset> AudioAssetProvider; // this is what I -want- to be using, not AssetProvider

class Manager
{
public:
    void AddProvider(AssetProvider& provider)
    {
        this->list.push_back(provider); // here is where there is usually a problem
    }

    template <typename T>
    T& GetAsset(std::string name)
    {
        Asset* asset = 0;

        for(std::vector<AssetProvider>::iterator i = this->list.begin(), l = this->list.end(); i != l; ++i)
        {
            if((*i).AssetExists(name))
            {
                asset = (*i).GetAsset(name);

                break;
            }
        }

        return static_cast<T&>(*asset);
    }

private:
    std::vector<AssetProvider> list;
};



int main()
{
    Asset* asset = new AudioAsset();

    AssetProvider provider;

    provider.AddAsset("meow", asset);

    Manager manager;

    manager.AddProvider(provider);

    AudioAsset asset2 = manager.GetAsset<AudioAsset>("meow");

    std::cout << asset2.name;
}
Thanks in advance