編輯:將示例代碼更改為我的專案中不起作用的代碼。
我正在用 C 撰寫代碼,學習模板并且遇到了一些問題。有一堂課:
template<class T, class Cmp>
class AVLtree {
public:
AVLtree(const Cmp& _cmp) : root(nullptr), cmp(_cmp) {}
AVLtree(const AVLtree& ref);
~AVLtree();
AVLtree& operator = (const AVLtree& ref);
void Add(const T& key);
void TraverseDfs(void (*visit)(const T& key));
private:
struct Node {
Node* left;
Node* right;
T key;
int balance;
unsigned int height;
unsigned int inheritence;
Node(const T& _key) : left(nullptr), right(nullptr), key(_key), balance(0), height(1), inheritence(1) {}
};
Node* root;
Cmp cmp;
void deleteTree(Node* root);
void traverse(Node* node, void(*visit) (const T& key));
Node* addNode(Node* node, const T& key);
Node* removeNode(Node* p, T key);
int bfactor(Node* node);
unsigned int height(Node* node);
void fixheight(Node* node);
Node* rotateRight(Node* p);
Node* rotateLeft(Node* q);
Node* balance(Node* p);
Node* findmin(Node* p);
Node* removemin(Node* p);
};
我想在addNode(Node* node, const T& key)課堂外定義方法,這就是我寫的:
template<class T, class Cmp>
AVLtree<T, Cmp>::Node* AVLtree<T, Cmp>::addNode(Node* node, const T& key) {
return new Node(key);
if (!node) {
return new Node(key);
}
if (cmp(key, node->key)) {
node->left = addNode(node->left, key);
}
else {
node->right = addNode(node->right, key);
}
}
然后我嘗試運行程式并得到這樣的錯誤和警告:
警告 C4346:“節點”:從屬名稱不是型別
message : 帶有“typename”前綴以指示型別
錯誤 C2061:語法錯誤:識別符號“節點”
錯誤 C2143:語法錯誤:缺少“;” 前 '{'
錯誤 C2447:“{”:缺少函式頭(舊式正式串列?)
似乎我做錯了什么,因為如果我addNode(Node* node, const T& key)在類中定義方法,它可以正常作業:
template<class T, class Cmp>
class AVLtree {
public:
...
private:
...
Node* addNode(Node* node, const T& key) {
return new Node(key);
if (!node) {
return new Node(key);
}
if (cmp(key, node->key)) {
node->left = addNode(node->left, key);
}
else {
node->right = addNode(node->right, key);
}
}
};
任何猜測可能是什么問題?
uj5u.com熱心網友回復:
感謝您的回答。得到了解決方案:
剛剛typename在類外的方法定義之前添加。它看起來像這樣:
template<class T, class Cmp>
typename AVLtree<T, Cmp>::Node* AVLtree<T, Cmp>::addNode(Node* node, const T& key) {
...
}
這似乎是 Visual Studio 的一些特殊化,因為我可以看到其他編譯器可以很好地處理此類代碼而沒有任何錯誤。
uj5u.com熱心網友回復:
看來我做錯了什么
不,這是微軟編譯器舊版本中著名的“錯誤/功能”。
在C1<T>::Work定義主體內,名稱查找Node應該是 find C1<T>::Node。有關更多資訊,請參閱cppreference.com 上的名稱查找:
成員函式定義
對于在成員函式體內使用的名稱、成員函式的默認引數、成員函式的例外說明或默認成員初始化器,搜索的范圍與類定義中的相同,只是類的整個范圍被考慮,而不僅僅是使用該名稱的宣告之前的部分。對于嵌套類,將搜索封閉類的整個主體。
您的代碼被其他編譯器接受,例如 gcc:
template<class T>
class C1 {
public:
void CallWork() { Work(); }
private:
struct Node {
T x;
};
Node* Work();
};
template<class T>
C1<T>::Node* C1<T>::Work()
{
return new Node{1};
}
現場演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/473694.html
