У меня есть определенный класс шаблонов. В этом классе я определяю структуру (struct NodeData), которая используется для узлов графа. Для первого кода, который я даю ниже, нет ошибки компиляции, даже если я специально делаю ошибку в тесте метода (я делаю g[nId].anything = "something"
, даже если у структуры NodeData нет переменной, называемой чем-либо).структура, определенная вне или внутри шаблона класса
Чтобы понять, где проблема, во втором коде, который я даю ниже, я поместил определения своих структур и typedefs вне MyClass. Я положил template<typename T1, typename T2>
поверх определения struct NodeData, потому что эта структура должна хранить 2 переменных абстрактного типа T1 и T2. Я также удалил ключевое слово typename
из typedefs, и я поставил NodeData<int, int>
вместо NodeData
в первом typedef (даже если я не хочу этого делать на самом деле), иначе он даст некоторые ошибки в этой строке, например: expected a type, got 'NodeData'
. Когда я компилирую, он дает следующую ожидаемую ошибку (что на самом деле абсолютно нормально): 'struct NodeData<int, int>' has no member named 'anything'
, а для первого кода я не получил эту ошибку!
В чем разница между этими двумя кодами? Как я могу сделать для второго кода не обязано указывать NodeData для первого typedef (поскольку члены var1 и var2 структуры NodeData не обязательно имеют тип 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()
{
// ...
}
ли вы на самом деле вызвать функцию пустоте MyClass :: тест (T1 arg1, T2 arg2) в первом случае? Если это не так, он не создается и, следовательно, в вашем коде нет ошибки. –
P3trus
Ну, я еще не создал его, я все еще пишу код для него. Итак, наконец, первый код был абсолютно правильным? – shn
Нет, это не так, но компилятор не видит ошибки, потому что не использует ее. – P3trus