我定义了一个简单的模板类。在这个类中,我定义了一个用于图节点的结构(struct NodeData)。对于我在下面给出的第一个代码,即使我在方法测试中故意犯了错误,也没有编译错误(g[nId].anything = "something"
即使 struct NodeData 没有名为任何变量的变量)。
为了理解问题出在哪里,在下面给出的第二个代码中,我将结构定义和 typedef 放在了 MyClass 之外。我已经把template<typename T1, typename T2>
结构 NodeData 的定义放在了上面,因为这个结构需要存储 2 个抽象类型 T1 和 T2 的变量。我还typename
从 typedefs 中删除了关键字,并且我在第一个 typedef 中放置NodeData<int, int>
了而不是NodeData
(即使我实际上不想这样做),否则它会在这一行出现一些错误,例如:expected a type, got 'NodeData'
. 当我编译时,它给出了以下预期的错误(这实际上是完全正常的):,'struct NodeData<int, int>' has no member named 'anything'
而对于第一个代码我没有得到这个错误!
这两个代码有什么区别?如何使第二个代码不必为第一个 typedef 指定 NodeData(因为 struct NodeData 的成员 var1 和 var2 不一定是 int 类型)?或者我怎样才能让第一个代码正常工作并检测 NodeData has no member named 的错误anything
?
第一个代码:
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
using namespace std;
using namespace boost;
template<typename T1, typename T2>
class MyClass
{
public:
MyClass();
virtual ~MyClass();
void test(T1 p, T2 s);
protected:
struct NodeData
{
T1 var1;
T2 var2;
int var3;
};
struct EdgeData
{
int var;
};
typedef adjacency_list<setS, setS, undirectedS, NodeData, EdgeData> Graph;
typedef typename Graph::vertex_descriptor NodeDataID;
typedef typename Graph::edge_descriptor EdgeDataID;
typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;
Graph g;
};
template<typename T1, typename T2>
void MyClass<T1, T2>::test(T1 arg1, T2 arg2)
{
NodeDataID nId = add_vertex(g);
g[nId].anything = "but anything is not in struct NodeData !";
g[nId].var1 = arg1;
g[nId].var2 = arg2;
g[nId].var3 = 55;
}
template<typename T1, typename T2>
MyClass<T1, T2>::MyClass()
{
// ...
}
template<typename T1, typename T2>
MyClass<T1, T2>::~MyClass()
{
// ...
}
第二个代码:
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
using namespace std;
using namespace boost;
template<typename T1, typename T2>
struct NodeData
{
T1 var1;
T2 var2;
int var3;
};
struct EdgeData
{
int var;
};
typedef adjacency_list<setS, setS, undirectedS, NodeData<int, int>, EdgeData> Graph;
typedef Graph::vertex_descriptor NodeDataID;
typedef Graph::edge_descriptor EdgeDataID;
typedef graph_traits<Graph>::vertex_iterator VertexIterator;
template<typename T1, typename T2>
class MyClass
{
public:
MyClass();
virtual ~MyClass();
void test(T1 p, T2 s);
protected:
Graph g;
};
template<typename T1, typename T2>
void MyClass<T1, T2>::test(T1 arg1, T2 arg2)
{
NodeDataID nId = add_vertex(g);
g[nId].anything = "but anything is not in struct NodeData !";
g[nId].var1 = arg1;
g[nId].var2 = arg2;
g[nId].var3 = 55;
}
template<typename T1, typename T2>
MyClass<T1, T2>::MyClass()
{
// ...
}
template<typename T1, typename T2>
MyClass<T1, T2>::~MyClass()
{
// ...
}