Vector of shared pointers to templated classes

I have a templated class TaskRunner that takes a polymorphic type Task and I want to create a container of shared pointers to them.

class Task {
    virtual void run() = 0;
};

class LoudTask : Task {
    void run() {
        std::cout << "RUNNING!" << std::endl;
    }
};

class QuietTask : Task {
    void run() {
        std::cout << "running!" << std::endl;
    }
};

template<typename T> class TaskRunner {
    public:
        TaskRunner<T>() {
            task = std::make_unique<T>();
        }
    private:
        std::unique_ptr<T> task;
};


using Runner = std::shared_ptr<TaskRunner<Task>>;

However I get error: no matching member function for call to 'push_back' with:

std::vector<Runner> runners;

runners.push_back(std::make_shared<TaskRunner<QuietTask>>());
runners.push_back(std::make_shared<TaskRunner<LoudTask>>());

Due to:

note: candidate function not viable: no known conversion from ‘shared_ptr<TaskRunner>’ to ‘const shared_ptr<TaskRunner>’ for 1st argument

>Solution :

Implemented IgorTandetnik’s suggestion, and it works for me:

#include <iostream>

#include <memory>
#include <vector>

class Task {
    virtual void run() = 0;
};

class LoudTask : Task {
public:
    void run() {
        std::cout << "RUNNING!" << std::endl;
    }
};

class QuietTask : Task {
public:
    void run() {
        std::cout << "running!" << std::endl;
    }
};

class TaskRunnerBase
{
public:
    virtual void run() =0;
};

template <class T>
class TaskRunner: public TaskRunnerBase {
    public:
        TaskRunner():
            task(std::make_unique<T>()) {
        }
        void run() override
        {
            task->run();
        }
    private:
        std::unique_ptr<T> task;
};

int main()
{
    using Runner = std::shared_ptr<TaskRunnerBase>;
    std::vector<Runner> runners;
    
    runners.push_back(std::make_shared<TaskRunner<QuietTask>>());
    runners.push_back(std::make_shared<TaskRunner<LoudTask>>());

    runners[0]->run();
    runners[1]->run();
}

Output:

running!
RUNNING!

Leave a Reply