Search code examples
c++templatesobjectcomposite

c++ template containing object using same type T


I have a class MemoryPool with the following (shortened to relevant) code:

namespace System
{
    template <class T>
    class MemoryPool
    {
    public:
        // only constructor
        MemoryPool(const size_t itemsToInitNow, const size_t maxItems)
            : _maxItemsInMemoryPool(maxItems)
        {
            // initialize itemsToInitNow items immediately
            for(size_t i = 0; i < itemsToInitNow; ++i) {
                _container.push_back(MemoryItemSharedPointer(new MemoryItem<T>(_factory.CreateItem())));
            }
        }
            .. other stuff

    private:
            .. other stuff
        // private data members
        AbstractFactory<T> _factory;

When I instantiate an instance of the object elsewhere in my code, such as

new System::MemoryPool<ParticleShape>(10, 100);

I get the following compile error:

System::AbstractFactory<T>::CreateItem(void) could not deduce template argument for 'T'.

My AbstractFactory class is also a template class, I defined _factory as a private composite object of MemoryPool with type T. I would like it so whenever I instantiated an object of MemoryPool with a type, say MemoryPool of integers, it would initialize the composite _factory with type int.

Is there a way of doing this?

Edit: here is the CreateItem method, in its infancy:

 template <typename T>
 inline const std::shared_ptr<T> CreateItem()
 {
      return std::shared_ptr<T>(new T);
 }

Solution

  • You've cut out a lot of your code, but at a guess, you have something like this:

    template<typename T>
    class AbstractFactory {
    // ......
        template <typename T>
        inline const std::shared_ptr<T> CreateItem()
        {
            return std::shared_ptr<T>(new T);
        }
    };
    

    The inner template hides the outer value of T - to call this, you'd have to do something like:

    AbstractFactory<Anything> factory;
    std::shared_ptr<int> pInt = factory.CreateItem<int>();
    

    As you can see, the inner function has a completely independent template parameter from the outer class. You'll probably want to just remove the template parameter from the inner function, so it takes the outer class's template parameter.