从类方法返回结构指针

发布于 2025-01-27 04:31:30 字数 2537 浏览 2 评论 0原文

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

我正在用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&amp; key) out class,这是我写的:

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:'node':依赖名称不是类型

消息:带有'typeName'的前缀以指示类型

错误c2061:语法错误:标识符'node'

错误c2143:语法错误:丢失';'在'{'

之前

错误C2447:'{':缺少功能标头(旧式形式列表?)

看来我在做错了什么,因为如果我定义方法addnode(node* node* node,const t&amp; 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);
        }
     }
};

有什么猜测可能出了什么问题?

EDIT: Changed example code to code from my project that doesn't work.

I'm writing code in C++, learning templates and got stuck with some problem.
There's a 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);
};

I want to define method addNode(Node* node, const T& key) out of class and here's what I write:

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

Then I try to run program and get such errors and warnings:

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?)

It seems that I'm doing something wrong because, if I define method addNode(Node* node, const T& key) inside class, it works fine:

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

Any guesses what might be wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

与往事干杯 2025-02-03 04:31:30

感谢您的回答。有一个解决方案:

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

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

看来这是Visual Studio的一些调理化,因为我可以看到其他编译器在没有任何错误的情况下可以正常工作。

Thanks for answers. Got a solution:

Just added typename before method definition outside of class. It looks like this:

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

It seems that this is some spicialization of Visual Studio because I can see that other compilers work fine with such code without any errors.

青芜 2025-02-03 04:31:30

看来我做错了什么

c1&lt; t&gt; :: Work定义的主体内部,node的名称应该找到c1&lt; t&gt; :: 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};
}

live demo

It seems that I'm doing something wrong

No. This is a famous "bug/feature" from oldish version of Microsoft's compiler.

Inside the body of C1<T>::Work definition, the name lookup for Node is supposed to find C1<T>::Node. See Name lookup on cppreference.com for more information:

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.

Your code is accepted by other compilers, e.g. 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};
}

live demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文