Я пытаюсь определить граф, в котором класс вершины определяется шаблоном. Как затем определить указатель на эту шаблонную вершину в другом классе.
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
Как вы собираетесь взаимодействовать с Vertexs, когда они окажутся в 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()не чистой виртуальной функцией и дайте ей реализацию, либо используйте производный класс для реализации: