[英]Pointers to templated class
我試圖定義一個圖,其中頂點類是用模板定義的。 然后,如何在另一個類中定義指向此模板化頂點的指針。
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
類,只有類的模板。
一種簡單的方法是使用多態,因為無論如何您只存儲指針:
定義從其繼承的所有Vertex
實例的基類。
template<class T1, class T2>
class Vertex : VertexBase {
public:
virtual T1 run(T2) = 0;
};
struct VertexBase {
~VertexBase() = default;
template<class T1, class T2> T1 run(T2 x) {
return dynamic_cast<Vertex<T1,T2>&>(*this).run(x);
}
};
無論如何,還要看看std::function
,看看是否能很好地解決您的問題。
您可以指定如下類型:
std::map<std::string, Vertex<int, int>*> vertices;
或也使Graph
模板化:
template<class T1, class T2>
class Graph {
std::map<std::string, Vertex<T1, T2>*> vertices;
首先,正如我所說,您需要一個Vertex
繼承自的非模板基類:
struct Base
{
virtual ~Base() = default;
};
template<class T1, class T2>
class Vertex : public Base
{
public:
virtual T1 run(T2) = 0;
};
然后在Graph
函數中使用std::shared_ptr<Base>
代替Vertex*
:
class Graph {
std::map<std::string, std::shared_ptr<Base>> vertices;
public:
void run();
};
現在,當在Vertex
指針上調用run()
時,您需要對指針進行dynamic_cast
返回適當的派生類。 在您的情況下,您無法在Vertex*
上實際調用run()
,因為Vertex::run()
是純虛擬函數。
int main()
{
Graph g;
g.vertices["xyz"] = std::make_shared<Vertex<int, int>>();
// error: field type 'Vertex<int, int>' is an abstract class
}
如果要調用Vertex
,請將run()
設為非純虛函數並為其提供實現,或者使用派生類進行實現:
class Derived : public Vertex<int, int>
{
public:
int run(int n) { std::cout << n << '\n'; return 0; }
};
class Graph {
std::map<std::string, std::shared_ptr<Base>> vertices;
public:
template<class T2>
void call_run(std::shared_ptr<Base> p, T2 value)
{
if (auto derived = std::dynamic_pointer_cast<Derived>(p))
derived->run(value);
if (/* other derived classes... */);
}
void run();
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.