6 / 6 / 1
Регистрация: 25.02.2016
Сообщений: 335
|
||||||
1 | ||||||
Определение типа - наследника16.08.2017, 21:30. Показов 3888. Ответов 12
Метки нет (Все метки)
Здравствуйте!
Проблема в следующем: контейнер хранить любого наследника некоторого базового класса. Есть шаблонный метод, который в зависимости от наследника выполняет свои действия. Шаблонный метод видит всегда только базовый и не различает наследников
0
|
16.08.2017, 21:30 | |
Ответы с готовыми решениями:
12
Указатель типа базового класса на тип наследника Определение типа! Определение типа объекта Определение типа переменной |
4 / 4 / 0
Регистрация: 27.05.2017
Сообщений: 26
|
|||||||||||
16.08.2017, 22:00 | 2 | ||||||||||
Не совсем понял что ты хочешь сделать, но для того что бы хранить разные типы тебе может помочь кортеж, std::tuple, а касательно того что ты сейчас сделал.
vec[0] возвращает тип изначально заданный, то есть std::vector<Base1> vec; для определения передаваемого типа можно воспользоваться typeid(T).name(). Добавлено через 1 минуту
Ну вот посмотри.
1
|
6 / 6 / 1
Регистрация: 25.02.2016
Сообщений: 335
|
|
16.08.2017, 22:08 [ТС] | 3 |
TerroJames,
Суть именно в специализации шаблона. Каждая функция заточено под свой тип (Но все типы наследуются от одного). Я храню в контейнере потомков и затем мне нужно вызвать функцию от этого потомка. То есть компилятор должен сам определить какой тип на самом деле лежит в Base1 (Это может быть любой его потомок). Tuple с этой задачей справится только если последовательность типов не меняется. Но это не совсем то... Я хочу, чтобы вызывалась не базовая функция, а ее специализации в зависимости от типа. Но вектор определен как контейнер для Base1 и, видимо, нельзя в определить типы его потомков.
0
|
4 / 4 / 0
Регистрация: 27.05.2017
Сообщений: 26
|
||||||
16.08.2017, 22:14 | 4 | |||||
Не, то что я тебе сейчас кинул это просто пример того что тебе надо будет сделать, а typeid(T).name(). для понимания что ты именно приходит.
Тоже самое работает и так.
1
|
6 / 6 / 1
Регистрация: 25.02.2016
Сообщений: 335
|
|
16.08.2017, 22:21 [ТС] | 5 |
Дело в том, что контейнер наполняется в runtime/
А если нужно добавить в контейнер заранее неизвестный тип - наследник Base1? Вот тут и загвоздка
0
|
4 / 4 / 0
Регистрация: 27.05.2017
Сообщений: 26
|
|
16.08.2017, 22:43 | 6 |
То есть типо там может быть много данных ??
Добавлено через 3 минуты Или стоп, ты имеешь в виду может быть много наследников ? неизвестное количество?? Добавлено через 14 минут Ну, перечитав то что ты написал, я примерно понял что ты хочешь, Вообщем, тебе нужно скорее всего бинарное дерево, не помню если оно в stl, Ну вот там от одной переменной можно будет вызывать разно специализированные функции от всех наследников для одного типа, но и там мне кажется придётся использовать std::tuple.
0
|
6 / 6 / 1
Регистрация: 25.02.2016
Сообщений: 335
|
||||||
16.08.2017, 22:44 [ТС] | 7 | |||||
Да. Вектор содержит множество наследников. Все это заполняется в рантайме.
Далее хочу передать этих наследников в шаблонный метод. Нужно чтобы из vector<Base*> вызывался foo(vec[0]) с нужной специалиацией. Например:
0
|
4 / 4 / 0
Регистрация: 27.05.2017
Сообщений: 26
|
|
16.08.2017, 22:49 | 8 |
Ну попробуй vector<tuple>, или как я предложил до этого бинарное дерево.
P.S. реализовать можно все что угодно, главное что бы было желание.
1
|
6 / 6 / 1
Регистрация: 25.02.2016
Сообщений: 335
|
||||||
16.08.2017, 23:01 [ТС] | 9 | |||||
Можно. У меня получилось очень сильно извратиться через std::type_index и сложные контейнеры... Вышло 300+ строк. Но "побаловались и хватит". Такие велосипеды не нужны. Дело в архитектуре... не верно я подошел к задаче.
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||||||
16.08.2017, 23:04 | 10 | |||||
Сообщение было отмечено Kertis138 как решение
Решение
шаблоны - это такие маленький волшебники.
следующий код вычисляет фактические типы наследников, и выбирает соответствующую типам перегрузку: http://rextester.com/MZQCSN52990
очень сильно попахивает проблемой XY вы хотите что то не правильное. инфа 100%
1
|
73 / 69 / 38
Регистрация: 09.10.2012
Сообщений: 238
|
||||||
16.08.2017, 23:21 | 11 | |||||
Храните в векторе указатели и используйте не специализацию шаблона, а виртуальные функции.
1
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
16.08.2017, 23:33 | 12 |
Нет. В данном случае вектор хранит только Base1. Когда вы делаете push_back(Base2()) Base2() неявно кастится к Base1.
Шаблоны - не серебрянная пуля. И они работают на этапе компиляции. А у вас тип определяется в рантайме. Ну так и используйте прямо предназначенные для этого средства языка (виртуальные функции). В векторе можно хранить shared_ptr, например.
1
|
6 / 6 / 1
Регистрация: 25.02.2016
Сообщений: 335
|
|||||||||||
17.08.2017, 11:50 [ТС] | 13 | ||||||||||
Нашел приемлемое решение через CRTP.
Получился вот такой код:
0
|
17.08.2017, 11:50 | |
17.08.2017, 11:50 | |
Помогаю со студенческими работами здесь
13
Определение нужного типа Определение введенного типа Определение типа окна Определение типа треугольника Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |