Как вернуть значение на которое указывает указатель?

Решил попробовать сделать list как в python только на с++, и столкнулся с проблемой того что мне возвращается не значение и не его тип, а родительский абстрактный класс. Вот у меня есть метод

_NODISCARD auto operator[](const size_t pos) const {
using ItemType = decltype(*list[pos].get());
return static_cast<Derived<ItemType>&>(*list[pos]).val;
}

и тут он вроде бы должен возвращать тип элемента по индексу, но возвращает класс Base, а надо например int и значение 5. Как решить эту проблему чтобы он возвращал правильный тип и значение элемента по индексу. Вот полный код

#pragma once

#ifndef _TYPELIST_H
#define _TYPELIST_H

#if __cplusplus >= 201703L
#error "This library requires a C++17 compliant compiler"
#else

#include <vector>
#include <type_traits>
#include <initializer_list>
#include <memory>
#include <stdexcept>

namespace collections {

namespace type_list {

    class type_list
    {
    private:
        struct Base;
        template<class _Ty>
        struct Derived;

        std::vector<std::unique_ptr<Base>> list;
        size_t size = 0;
    public:
        type_list() = default;

        template<class... _Ty>
        type_list(_Ty... values) {
            (append(values), ...);
        }

        template<class _Ty>
        void append(_Ty val) {
            list.push_back(std::make_unique<Derived<_Ty>>(val));
            size++;
        }

        void pop(const size_t pos = -1) {
            list.erase(pos >= size ? list.end() : list.begin() + pos);
            size--;
        }

        template<class _Ty>
        void remove(_Ty val) {
            for (size_t i = 0; i < list.size(); i++)
            {
                if (list[i].get() == val) { list.erase(list.begin() + i); return; }
            }
            throw std::out_of_range(std::strcat(val + " not in the list"));
        }

        _NODISCARD inline size_t len() const noexcept {
            return size;
        }

        _NODISCARD auto operator[](const size_t pos) const {
            using ItemType = decltype(*list[pos].get());
            return static_cast<Derived<ItemType>&>(*list[pos]).val; 
        }

        /*_NODISCARD auto at(const size_t pos) const {
            if (pos >= size) throw std::out_of_range("invalid pos");
            else return this->operator[](pos);
        }*/

        void clear() {
            list.clear();
            size = 0;
        }

    private:
        struct Base
        {
            virtual ~Base() = default;
        };

        template<class _Ty>
        struct Derived : public Base
        {
            _Ty val;
            Derived(_Ty val) : val(val) {}
        };
    };

    /*template<class _Mylist>
    class type_list_const_iterator : {
    public:
        type_list_const_iterator()
        {
        }

        ~type_list_const_iterator()
        {
        }

    private:

    };*/

}
}
#endif
#endif

Ответы (0 шт):