Обновление std :: shared_ptr <Derived>до std :: shared_ptr <Base>с шаблонами - PullRequest
1 голос
/ 30 марта 2020

У меня есть 4 класса в цепочке наследования: A-> B -> C, A-> B-> D, где B - единственный шаблон класса.

Я хотел бы иметь std :: map, который отображается между идентификаторами и указателями объектов (C или D), но у меня возникают проблемы с назначением вывода make_shared для записи в std :: map.

Самое смешное, что схожий пример, но без промежуточного класса шаблона, компилируется нормально, так что я думаю, это связано с этим.

#include <iostream>
#include <map>
#include <memory>

class A
{
    public:
        int i;
    protected:
        A(int j) : i(j) {}
};

template <typename T>
class B : protected A
{
    protected:
        T t;
        B(int i) : A(i) {}
};

class C : protected B<int>
{
    public:
        C(int i) : B(i) {}
};

class D : protected B<float>
{
    public:
        D(float i) : B(i) {}
};

int main()
{
    std::map<std::string, std::shared_ptr<A>> map; // [id, object ptr]

    map["c"] = std::make_shared<C>(0); // error here
    map["d"] = std::make_shared<D>(1.0); // error here

    for (auto i : map)
    {
        std::cout << i.first << i.second->i << std::endl;
    }

    return 0;
}

Ошибка компилятора:

main.cpp:37:37: error: no match for ‘operator=’ (operand types are ‘std::map<std::__cxx11::basic_string<char>, std::shared_ptr<A> >::mapped_type {aka std::shared_ptr<A>}’ and ‘std::shared_ptr<C>’)
     map["c"] = std::make_shared<C>(0); // error

1 Ответ

2 голосов
/ 30 марта 2020

Ваша попытка конверсии находится за пределами класса и его детей. Это не может работать, потому что наследование не публикуется c. Чтобы исправить это, сделайте наследство publi c. Также можно выполнить преобразование внутри функции-члена.

...