@232321fdsa

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

Всем привет, я решил попробовать сделать 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

Помогите пожалуйста!!!!!! Очень надо.
  • Вопрос задан
  • 145 просмотров
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Вот как вы себе представляете: вызов одной и той же функции должен вернуть разные типы для разных индексов?

Нет, в C++ статическая типизация, одна функция может вернуть только один тип. Из List'а вы только Base вернуть и можете. А уже как-то опросив экземпляр класса с помощью виртуальных методов, вы сможете узнать, какого же он на самом деле типа и скастовать к нему.

В крайнем случае, можно сделать шаблонный метод, который будет возвращать тип, указанный в параметре шаблона. Но, опять же, вызывающий код должен будет сам решить, а какой же тип ему нужен.

Или хранте и возвращайте std::Variant, а не указатели на базовый класс.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы