从 class 方法返回结构指针

Returning a struct pointer from class method

编辑:将示例代码更改为我的项目中不起作用的代码。

我正在用 C++ 编写代码,学习模板,但遇到了一些问题。 有一个 class:

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);
};

我想从 class 中定义方法 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);
    }
}

然后我尝试运行编程并得到这样的错误和警告:

warning C4346: 'Node': dependent name is not a type

message : prefix with 'typename' to indicate a type

error C2061: syntax error: identifier 'Node'

error C2143: syntax error: missing ';' before '{'

error C2447: '{': missing function header (old-style formal list?)

似乎我做错了什么,因为如果我在 class 中定义方法 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);
        }
     }
};

猜猜哪里出了问题?

It seems that I'm doing something wrong

没有。这是 Microsoft 编译器旧版本中著名的“bug/feature”。

C1<T>::Work 定义的主体内,Node 的名称查找应该找到 C1<T>::Node。有关详细信息,请参阅 Name lookup on cppreference.com

Member function definition

For a name used inside a member function body, a default argument of a member function, exception specification of a member function, or a default member initializer, the scopes searched are the same as in class definition, except that the entire scope of the class is considered, not just the part prior to the declaration that uses the name. For nested classes the entire body of the enclosing class is searched.

您的代码被其他编译器接受,例如海合会:

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};
}

live demo

感谢您的回答。得到解决方案:

刚刚在 class 之外的方法定义之前添加了 typename。它看起来像这样:

template<class T, class Cmp>
typename AVLtree<T, Cmp>::Node* AVLtree<T, Cmp>::addNode(Node* node, const T& key) {
   ... 
}

这似乎是 Visual Studio 的一些特殊化,因为我可以看到其他编译器可以很好地处理此类代码而不会出现任何错误。