Я пытаюсь определить граф, в котором класс вершины определяется шаблоном. Как затем определить указатель на эту шаблонную вершину в другом классе.
template<class T1, class T2>
class Vertex {
public:
virtual T1 run(T2) = 0;
};
class Graph {
std::map<std::string, Vertex*> vertices; // <--- How do I do something like this
int** adjacency_matrix;
public:
void run() {
...
}
};
Я рассматривал некоторые другие вопросы по Stack-Overflow, общее предложение, похоже, состоит в том, чтобы использовать базовый класс, который не является шаблоном, и использовать для этого указатели и помещать общие функции в этот класс. Однако в моем коде функция run()
, которая является общей и использует шаблон для типа возвращаемого значения. Поэтому я не понимаю, как использовать базовый класс.
Любые идеи?
Если функция Vertex::run
использует аргументы шаблона и вы хотите сохранить указатели на Vertex
без аргументов шаблона, как вы собираетесь вызывать Vertex::run
? Что вы собираетесь на это переходить? — person ssb schedule 24.06.2014
Вот такая у меня проблема. Есть ли у вас какие-либо предложения, чтобы обойти это? — person ssb schedule 24.06.2014
C ++ имеет статическую типизацию, поэтому ему необходимо знать тип во время компиляции. Это означает, что ему нужно знать, что такое T2
, если вы собираетесь позвонить run(T2)
. Вы можете объявить несколько карт в Graph
, по одной для каждой комбинации аргументов шаблона Vertex
, которые вы используете, но это звучит не очень хорошо. Возможно, вам придется пересмотреть свой дизайн и посмотреть, есть ли другой способ решения вашей проблемы. Чего вы пытаетесь достичь? Вы можете задать другой вопрос, более направленный на это. — person ssb schedule 24.06.2014
Как вы собираетесь взаимодействовать с Vertex
s, когда они окажутся в Graph
, не зная их типа? — person ssb schedule 24.06.2014
Класса с именем
Vertex
не существует, только шаблон для классов.Простой выход — использовать полиморфизм, так как вы все равно храните только указатели:
Определите базовый класс, от которого наследуются все
Vertex
экземпляры (специализированные или нет).В любом случае, также взгляните на
std::function
и посмотрите, достаточно ли это решает вашу проблему.Проблема с базовым классом заключается в том, что мне нужно использовать функцию
run()
, которая использует шаблон. Как определить это в базовом классе? — person ssb; 24.06.2014Добавлен пример использования шаблона в базовом классе для вызова
run
. — person ssb; 24.06.2014Вы можете указать такой тип:
Или сделайте
Graph
шаблонным:Дело в том, что карта может иметь разные реализации шаблона класса
Vertex
. Например, одна запись может бытьVertex<int, int>
, другая может бытьVertex<double, long>
и т. Д. — person ssb; 24.06.2014@subzero Можете воспользоваться моим вторым предложением. — person ssb; 24.06.2014
Но когда я создаю экземпляр объекта Graph в этом случае, я бы застрял только с одним типом объектов Vertex. — person ssb; 24.06.2014
Нет, вы можете сделать
Graph<double, long>
. — person ssb; 24.06.2014Я имею в виду, что если я создам экземпляр, скажите
Graph<int, int> x
. Тогда я не могуx.vertices['xyz'] = 1.12121
. — person ssb; 24.06.2014@subzero Создайте базовый класс, от которого наследуется
— person ssb; 24.06.2014
Vertices
. Теперь заменитеVertices*
на карте наBase*
(или любое другое имя по вашему выбору). Затем вы можете динамически выделить класс шаблона с нужными параметрами. Но также рекомендуется использовать интеллектуальные указатели, такие какstd::shared_ptr
, чтобы управлять памятью за вас.@ 0x499602D2 Но как мне определить функцию
run()
вBase
(которая использует шаблон)? Я не могу получить доступ к функцииrun()
изBase*
. — person ssb; 24.06.2014@CoffeeandCode. Когда вы запускаете код из этого ответа и вызываете
run()
, вы получаете эту ошибку. — person ssb; 24.06.2014Во-первых, как я уже сказал, вам нужен не шаблонный базовый класс, от которого
Vertex
наследуется:Затем внутри вашей
Graph
функции вы используетеstd::shared_ptr<Base>
вместоVertex*
:Теперь при вызове
run()
указателяVertex
вам нужноdynamic_cast
вернуть указатель обратно на соответствующий производный класс. В вашем случае вы не можете вызватьrun()
наVertex*
, посколькуVertex::run()
— это чистая виртуальная функция.Если вы хотите вызвать
Vertex
, либо сделайтеrun()
не чистой виртуальной функцией и дайте ей реализацию, либо используйте производный класс для реализации: