Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
relationer
33 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 118
#1

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

07.07.2014, 12:34. Просмотров 636. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Хранение вектора экземпляров шаблонного класса неизвестного типа (C++):

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

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

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

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

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

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
dzrkot
zzzZZZ...
519 / 349 / 53
Регистрация: 11.09.2013
Сообщений: 1,998
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!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 3
08.07.2014, 12:17 #4
relationer,
C++
1
std::vector<boost::any>>
0
Ilot
Модератор
Эксперт С++
1811 / 1168 / 229
Регистрация: 16.05.2013
Сообщений: 3,082
Записей в блоге: 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
Модератор
Эксперт С++
1811 / 1168 / 229
Регистрация: 16.05.2013
Сообщений: 3,082
Записей в блоге: 5
Завершенные тесты: 1
08.07.2014, 14:50 #7
Цитата Сообщение от relationer Посмотреть сообщение
Ilot, спасибо, но проблема в том, что производных-то будет много, и некоторые из них будут определены не мной.
Ну так поэтому метод шаблонный. Сколько хотите столько и используйте типов. Это могут делать и пользователи вашей библиотеки.
0
Voivoid
675 / 278 / 12
Регистрация: 31.03.2013
Сообщений: 1,339
08.07.2014, 16:10 #8
Цитата Сообщение от gray_fox Посмотреть сообщение
std::vector<boost::any>>
Или, что на мой взгял гораздо лучше, - boost::variant

Цитата Сообщение от relationer Посмотреть сообщение
хорошо, но у меня нет желания таскать за собой многотонные библиотеки.
Всегда лоллирую с подобных аргументов. Место на жестком диске что-ли заканчивается? Люди написали массу полезных библиотек - берите, пользуйтесь. Нет, хотят писать кривые велосипеды
0
DrOffset
7136 / 4277 / 964
Регистрация: 30.01.2014
Сообщений: 7,066
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
675 / 278 / 12
Регистрация: 31.03.2013
Сообщений: 1,339
09.07.2014, 12:39 #11
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Сколько можно-то головой об стену биться. Не надо пытаться победить типизацию, лол. Все можно сделать оставаясь в рамках системы типов. Почитай про type erasure, скорее всего это то, что тебе нужно. Ну или просто напиши что ты пытаешься решить таким вот образом.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.07.2014, 12:39
Привет! Вот еще темы с ответами:

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

Как создать элемент вектора пользовательского типа(класса)? - C++
Делаю змейку в консоли, а по сути тренируюсь с классами и векторами. Есть класс с конструктором который создает кусок змейки в...

Написать функцию для класса, возращающую данный из вектора обьектов класса по итератору вектора - C++
День=добрый как написать функцию для класса возращающую данный из вектора обьектов класса по итератору вектора?? стока запроса: ...

Возможно ли создание объекта шаблонного класса в функции этого класса? - C++
Доброго времени суток, уважаемые форумчане :) Мне по лабам задали задание - реализовать шаблон контейнера (множество) с операциями...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.07.2014, 12:39
Ответ Создать тему
Опции темы

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