私は単純なテンプレートクラスを定義しています。このクラスでは、グラフのノードに使用される構造体(struct NodeData)を定義します。最初のコードでは、メソッドのテストでエラーが発生してもコンパイルエラーは発生しません(struct NodeDataには何も呼び出されていなくてもg[nId].anything = "something"
)。構造体がクラステンプレートの外側または内側に定義されています
問題は、私はMyClassの外で私の構造体の定義とのtypedefを入れている怒鳴る与える第二のコードでは、ここで理解します。この構造体は抽象型T1とT2の2つの変数を格納する必要があるため、struct NodeDataの定義の先頭にtemplate<typename T1, typename T2>
を入れました。また、typename
というキーワードをtypedefから削除しました。NodeData
の代わりにNodeData<int, int>
を最初のtypedefに入れました(実際にはしたくない場合でも)。expected a type, got 'NodeData'
のようないくつかのエラーが表示されます。私がコンパイルすると、次の予想されるエラーが発生します(これは実際には完全に正常です)。'struct NodeData<int, int>' has no member named 'anything'
、最初のコードではこのエラーは発生しませんでした。
この2つのコードの違いは何ですか? 2番目のコードでNodeDataを最初のtypedefに指定する必要はありません(struct NodeDataのメンバーvar1とvar2は必ずしもint型ではないため)。または、最初のコードが正常に動作するようにするにはどうしたらいいですか?NodeDataには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()
{
// ...
}
最初に、void MyClass :: test(T1 arg1、T2 arg2)関数を呼び出しますか?それがインスタンス化されないので、コードにエラーはありません –
P3trus
まあ、私はまだそれをインスタンス化していない、私はまだそれのためのコードを書いています。最終的に最初のコードはまったく正しいのですか? – shn
いいえ、それは正しくありませんが、コンパイラはエラーを見ることができません、彼はそれを使用しないためです。 – P3trus