Thread: Inherited Templates

  1. #1
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034

    Inherited Templates

    What's the proper to do this? I don't know the name.. virtual template inheritence? or many topics on the subject.. this? http://www.java2s.com/Tutorial/Cpp/0...nheritance.htm

    Code:
    #include <iostream>
    #include <string>
    
    class Resource
    {
    
    };
    
    class TileSet : public Resource
    {
    public:
        TileSet(const std::string& name)
        {
            this->name = name;
        }
    
        std::string name;
    };
    
    class Provider
    {
    
    };
    
    class TileSetProvider : public Provider
    {
    public:
        TileSet GetAsset(const std::string& name) { return TileSet(name); }
    
        static TileSetProvider Type;
    };
    
    TileSetProvider TileSetProvider::Type = TileSetProvider();
    
    class ResourceManager
    {
    public:
        template<typename B>
        B operator [](B& b)
        {
            return TileSetProvider();
        }
    
        //Provider* provider;
    };
    
    int main()
    {
        ResourceManager resourceManager;
    
        //resourceManager.AddProvider(TileSetProvider());
    
        TileSet grass = resourceManager[TileSetProvider::Type].GetAsset("grass");
    
        std::cout << grass.name << std::endl;
    }
    Instead of
    resourceManager[TileSetProvider::Type].GetAsset("grass")
    it could be
    resourceManager.GetAsset(TileSetProvider::Type, "grass")

    The "TileSetProvider::Type" is a bit ugly. I'd prefer to pass just "TileSet", but "TileSet" is the class name, and "TileSet::Type" wouldn't work because the template needs to know to return a TileSetProvider object (problem lies that template functions don't have the <> access operators (like C#) instead they naturally determine to types ). Which would be easy if I wanted to hardcode it all into the class, but I want it generic. Provider init/list and asset init/list removed for testing.

    This is a test. Not serious coding.

    I could also accomplish this using virtual functions that return Resource*, access resourceManager["TileSet"] and then static_cast<TileSet>
    Last edited by Dae; 01-13-2009 at 10:25 PM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    You seem to want Provider<B> to decay into a Provider<A> when A is a parent class of B. Templates just don't do that.

    Also, your AddProvider() and GetAsset() methods are templates, but they don't take any parameter dependent on the template variable, which means you have to specify the type when calling them. And even if you do that, the Create() function is going to return a Resource, which is incompatible with anything else except a subclass (and if it's a subclass, it will get sliced, there will be no polymorphism going on).

    I have only a very hazy picture of what you want to do so I can't really help. Suffice to say you should probably be using pointers in some places where you are using objects.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    nm. for now
    Last edited by m37h0d; 01-13-2009 at 08:56 PM.

  4. #4
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    I think you're looking for a "runtime" solution, not a compile-time one... I'm thinking more down the path of:

    Code:
    Code:
    
    #include <iostream>
    #include <string>
    
    class Resource
    {
    
    };
    
    class TileSet : public Resource
    {
    
    };
    
    class Provider
    {
    public:
        virtual Resource* Create() = 0;
    };
    
    class TileSetProvider : public Provider
    {
    public:
        virtual Resource* Create() { return new TileSet(); }
    };
    
    class ResourceManager
    {
    public:
        void AddProvider(Provider* p) { this->provider = p; } 
    
        template<typename B>
        B* GetAsset(std::string& name) { return dynamic_cast<B*>(this->provider->Create()); }
    
        Provider* provider;
    };
    
    int main()
    {
        ResourceManager resourceManager;
    
        resourceManager.AddProvider(new TileSetProvider());
    
        TileSet* ts = resourceManager.GetAsset<TileSet>("grass");
    }
    Though then again, more information on the application would be helpful... (as the provided example is not complete).

  5. #5
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by brewbuck View Post
    You seem to want Provider<B> to decay into a Provider<A> when A is a parent class of B. Templates just don't do that.

    Also, your AddProvider() and GetAsset() methods are templates, but they don't take any parameter dependent on the template variable, which means you have to specify the type when calling them. And even if you do that, the Create() function is going to return a Resource, which is incompatible with anything else except a subclass (and if it's a subclass, it will get sliced, there will be no polymorphism going on).

    I have only a very hazy picture of what you want to do so I can't really help. Suffice to say you should probably be using pointers in some places where you are using objects.
    Right I'm aware it's incorrect and templates don't work that way in C++ (you can make this work in C#) and that's why I'm asking the proper way.

    It's not final, and I don't care about references, pointers, etc. It's just a 5 minute test case.

    What I wanted to do is call a method (GetAsset) which returns a specified type (TileSet, Map, etc.). I wanted to use templates to avoid returning the base class and dynamic/static casting. You can do this in C# with method templates: ResourceManager.GetAsset<TileSet>("grass"); Unfortuntely C++ has no typeof operator, nor apparently virtual template methods in C++ because virtual is runtime and templates are compile time.

    source: http://groups.google.com/group/comp....b192d63c03f4a2

    I'm not complaining my code doesn't work. I just want to know the best possible equivalent in C++. I guess base/derived class casting.
    Last edited by Dae; 01-13-2009 at 09:25 PM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  6. #6
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    you can't ensure the the type you're specifying in getasset is the same type as the provider you've set (or added, as you've called it). the only way this is safe is to make resourcemanager a template class as well.

  7. #7
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by m37h0d View Post
    you can't ensure the the type you're specifying in getasset is the same type as the provider you've set (or added, as you've called it). the only way this is safe is to make resourcemanager a template class as well.
    I think you're right. In which case it would serve no purpose and could remove it and just go with providers.

    I'd still like to see some sort of struct, function pointer, register type of solution as long as it works as intended.

    I did figure out a *possible* method. Updating my original post.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  8. #8
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Here's the virtual method to which I'm referring. I don't know which is worse (virtual base class and casting, or templates). Both compile and seem to work fine (ignoring pointer/references). Yes, I do want to allow access to the derived class, not just the base class interface, so casting or templates are a must.

    Code:
    #include <iostream>
    #include <string>
    
    class Resource
    {
    public:
        virtual void DoSomething() = 0;
    };
    
    class TileSet : public Resource
    {
    public:
        TileSet(const std::string& name) { this->name = name; }
    
        void DoSomething() {}
    
        std::string name;
    };
    
    class Provider
    {
    public:
        virtual Resource* GetAsset(const std::string&) = 0;
    
        std::string tag;
    };
    
    class TileSetProvider : public Provider
    {
    public:
        TileSetProvider() { this->tag = "TileSet"; }
    
        Resource* GetAsset(const std::string& name)
        {
            TileSet* tileSet = new TileSet(name);
    
            return static_cast<Resource*>(tileSet);
        }
    };
    
    class ResourceManager
    {
    public:
        void AddProvider(Provider& provider)
        {
            this->provider = &provider;
            this->hash = &provider.tag;
        }
    
        Provider* operator [](std::string hash)
        {
            if(hash == "TileSet")
                return this->provider;
        }
    
        Provider* provider;
        std::string* hash;
    };
    
    int main()
    {
        ResourceManager resourceManager;
    
        TileSetProvider tilesetProvider;
    
        resourceManager.AddProvider(tilesetProvider);
    
        TileSet* grass = static_cast<TileSet*>(resourceManager["TileSet"]->GetAsset("grass"));
    
        std::cout << grass->name << std::endl;
    }
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 07-24-2006, 08:14 AM
  2. Questions about Templates
    By Shamino in forum C++ Programming
    Replies: 4
    Last Post: 12-18-2005, 12:22 AM
  3. Help With Inherited Classes Needed
    By elliott in forum C++ Programming
    Replies: 4
    Last Post: 12-11-2005, 09:05 AM
  4. templates and inheritance problem
    By kuhnmi in forum C++ Programming
    Replies: 4
    Last Post: 06-14-2004, 02:46 AM