Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
relationer
33 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 118
1

Хранение вектора экземпляров шаблонного класса неизвестного типа

07.07.2014, 12:34. Просмотров 745. Ответов 10
Метки нет (Все метки)

Здравствуйте!

Потребовалось хранить вектор экземпляров шаблонного класса неизвестного типа.
Для выделения фиксированного шаблона с фиксированным размером сделал так:
C++
1
std::vector<Type<void*, void*>>
Как потом переводить из, скажем, Type<int, double> в Type<void*, void*>?
Определять в Type конструкторы копирования/перемещения, operator= для перевода из случайного набора аргументов шаблона в void*, void* и обратно?

Как это можно сделать и как подобные проблемы вообще красиво решаются?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.07.2014, 12:34
Ответы с готовыми решениями:

Как корректно передать в метод шаблонного класса объект шаблонного класса в качестве параметра?
header.h template &lt;class T&gt; class MyVector { public: void...

Определение типа члена шаблонного класса
Такая проблема. Есть шаблонный класс с членом - указателем, тип которого должен...

Перегрузка оператора шаблонного класса в зависимости от типа
Как заставить шаблон различать тип переменной которую ему передают? Пробую...

Различное поведение конструктора шаблонного класса в зависимости от типа параметра
Здравствуйте. Возникла проблема - при попытке изменить поведение конструктора...

Decltype при определении возвращаемого типа в перегруженных операторах шаблонного класса
Для всех следующих примеров будет использован main(): #include &lt;iostream&gt; int...

10
dzrkot
zzzZZZ...
523 / 354 / 94
Регистрация: 11.09.2013
Сообщений: 2,039
07.07.2014, 12:51 2
мб vector сделать частью класса
C++
1
2
3
<class T1,classT2,class T3>
vector<T1<T2,T3> >
....
0
relationer
33 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 118
08.07.2014, 12:15  [ТС] 3
К сожалению, это не вариант. Как можно по-другому это сделать?
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
08.07.2014, 12:17 4
relationer,
C++
1
std::vector<boost::any>>
0
Ilot
Эксперт С++
1831 / 1189 / 342
Регистрация: 16.05.2013
Сообщений: 3,139
Записей в блоге: 5
Завершенные тесты: 1
08.07.2014, 12:20 5
Возможно запилить в классе Type приведение типа:
C++
1
2
3
4
template <typename T1, typename T2>
operator Type<T1, T2> () {
    /*...*/
}
0
relationer
33 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 118
08.07.2014, 14:46  [ТС] 6
gray_fox, хорошо, но у меня нет желания таскать за собой многотонные библиотеки.
Ilot, спасибо, но проблема в том, что производных-то будет много, и некоторые из них будут определены не мной.
0
Ilot
Эксперт С++
1831 / 1189 / 342
Регистрация: 16.05.2013
Сообщений: 3,139
Записей в блоге: 5
Завершенные тесты: 1
08.07.2014, 14:50 7
Цитата Сообщение от relationer Посмотреть сообщение
Ilot, спасибо, но проблема в том, что производных-то будет много, и некоторые из них будут определены не мной.
Ну так поэтому метод шаблонный. Сколько хотите столько и используйте типов. Это могут делать и пользователи вашей библиотеки.
0
Voivoid
708 / 280 / 16
Регистрация: 31.03.2013
Сообщений: 1,339
08.07.2014, 16:10 8
Цитата Сообщение от gray_fox Посмотреть сообщение
std::vector<boost::any>>
Или, что на мой взгял гораздо лучше, - boost::variant

Цитата Сообщение от relationer Посмотреть сообщение
хорошо, но у меня нет желания таскать за собой многотонные библиотеки.
Всегда лоллирую с подобных аргументов. Место на жестком диске что-ли заканчивается? Люди написали массу полезных библиотек - берите, пользуйтесь. Нет, хотят писать кривые велосипеды
0
DrOffset
8130 / 4713 / 1152
Регистрация: 30.01.2014
Сообщений: 7,683
08.07.2014, 16:18 9
Цитата Сообщение от Voivoid Посмотреть сообщение
Место на жестком диске что-ли заканчивается?
Насколько я помню, any и variant вообще header-only библиотеки. Так что таскать их с собой не надо будет.

Добавлено через 28 секунд
С другой стороны, все еще не совсем понятно что же именно хочет ТС.
0
relationer
33 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 118
09.07.2014, 12:30  [ТС] 10
Товарищи, я написал один приблизительный вариант кода как решение данной проблемы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// main.cpp
#include <iostream>
 
#include "derived_type.hpp"
#include <vector>
 
int main()
{
    std::vector<UnspecifiedBaseTypePtr> vec = { };
 
    vec.push_back(DerivedType<void*, int*>());
 
    BaseType<void*, int*>::specify(vec[0])->doSomething();
 
    return 0;
}
 
// base_type.hpp
 
#ifndef BASE_TYPE_HPP
#define BASE_TYPE_HPP
 
template<typename R, typename A>
class BaseType;
 
using UnspecifiedBaseTypePtr = BaseType<void*, void*>*;
 
template<typename R, typename A>
class BaseType
{
public:
    BaseType();
 
    virtual void doSomething();
 
    operator UnspecifiedBaseTypePtr();
 
    static BaseType* specify(UnspecifiedBaseTypePtr);
    static UnspecifiedBaseTypePtr getUnspecified(BaseType*);
};
 
#include "base_type.cpp"
 
#endif
 
// base_type.cpp
 
#ifdef BASE_TYPE_HPP
 
template<typename R, typename A>
BaseType<R, A>::BaseType()
{ }
 
template<typename R, typename A>
BaseType<R, A>::operator UnspecifiedBaseTypePtr()
{
    return BaseType<R, A>::getUnspecified(this);
}
 
/* STATIC */
 
template<typename R, typename T>
BaseType<R, T>* BaseType<R, T>::specify(UnspecifiedBaseTypePtr u)
{
    static_assert(std::is_pointer<R>::value && std::is_pointer<T>::value,
          "Could not convert to specified Type due to non-pointer template arguments.");
 
    return reinterpret_cast<BaseType<R, T>*>(u);
}
 
template<typename R, typename T>
UnspecifiedBaseTypePtr BaseType<R, T>::getUnspecified(BaseType<R, T>* s)
{
    static_assert(std::is_pointer<R>::value && std::is_pointer<T>::value,
          "Could not convert to unspecified type due to non-pointer template arguments.");
 
    return reinterpret_cast<UnspecifiedBaseTypePtr>(s);
}
 
#endif
Это было бы идеально - небезопастность reinterpret_cast компенсируется static_assert, но у этого подхода есть два больших минуса:
  1. Необходимость передавать указатели как аргументы шаблона -> потенциальные проблемы с утечками памяти, ну и не особо красиво выглядит
  2. Иногда в качестве аргумента шаблона необходимо передавать void, что становится невозможным

Как можно решить эти проблемы?
Существует ли какой-то другой способ хранить массив унаследованных шаблонов?

P. S. я согласен, что излишнее велосипедостроение плохо, и сам стараюсь использовать какие-либо сторонние решения, но мне в данном случае была поставлена задача написать все без сторонних библиотек. Извините, boost хорош, но сегодня он не подойдет.
0
Voivoid
708 / 280 / 16
Регистрация: 31.03.2013
Сообщений: 1,339
09.07.2014, 12:39 11
Лучший ответ Сообщение было отмечено relationer как решение

Решение

Сколько можно-то головой об стену биться. Не надо пытаться победить типизацию, лол. Все можно сделать оставаясь в рамках системы типов. Почитай про type erasure, скорее всего это то, что тебе нужно. Ну или просто напиши что ты пытаешься решить таким вот образом.
1
09.07.2014, 12:39
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.07.2014, 12:39

Явная специализация метода для типа шаблонного класса
Добрый вечер, уважаемые знатоки! :) Хочу задать вопрос по созданию шаблонов. В...

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

Возврат объекта шаблонного типа от типа Type из специализации шаблона метода от того же типа
Доброго времени суток, пишу класс содержащий несколько std::set от разных...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru