【问题标题】:How do I write a member function that returns a type that only exists in the class?如何编写返回只存在于类中的类型的成员函数?
【发布时间】:2018-09-25 12:57:53
【问题描述】:

我实际上是在 C++ 中实现一个双向链表。

这是一个 MWE:

namespace mynamespace {

template <typename T>
class List {
public:
    List();

    void prepend(T);
    void append(T);
    void remove(T);

private:
    struct Node {
        T value_;
        Node * prev_;
        Node * next_;
    };

private:
    Node * find(T); // <-- THIS IS MY PROBLEM

private:
    Node * head_;
    Node * tail_;
};

}

我想创建该函数的原因是因为我认为如果我可以使用这样的函数遍历列表直到找到给定的元素(我需要对remove() 函数反正)

但是如何在 class 定义之外定义该函数?

由于NodeList 类的私有成员,所以这不起作用:

template <typename T>
Node * List<T>::find(T val)
{
    // stuff
}

我想定义函数 inside class 定义会起作用,因为 Node 在那里有意义...这是正确的方法吗?即使是这样,我想也必须有一种方法可以按照我尝试的方式定义函数......

【问题讨论】:

  • 就像你必须做List&lt;T&gt;::find 告诉编译器find 在哪里你需要对Node 做同样的事情。
  • @Justin 谢谢,这行得通!我错过了typename(我尝试了你和@NathanOliver 最初所说的,但我认为那也是错误的,因为没有typename,我得到了错误)。您能否将此添加为答案,以便我将其标记为解决方案?另外,你能解释一下为什么我需要typename吗?
  • 请注意,在模板中,我通常倾向于使用const T&amp; 参数而不是T,因此如果T 类似于std::string,则不会有不必要的副本。 (一个可能的例外是像 prependappend 这样的“插入”类型操作,您可以在其中使用按值传递,然后将参数 move 到容器中,以避免必须编写单独的副本 prepend(const T&amp;) 并移动 prepend(T&amp;&amp;) 版本的方法。)

标签: c++ list


【解决方案1】:

因为NodeList 类的私有成员,所以这不起作用:

实际上,这是不正确的。这不是因为Node 是私有的,而是因为Node 嵌套在List 中。 Node 类的名称不是 Node,而是 List&lt;T&gt;::Node。但是,既然Nodedepends on T,就得写typename List&lt;T&gt;::Node,否则编译器会假定List&lt;T&gt;::Node是一个值而不是一个类型。请参阅this question 了解更多信息。

简而言之,替换为:

template <typename T>
Node * List<T>::find(T val)

有了这个:

template <typename T>
typename List<T>::Node * List<T>::find(T val)

或者,正如 StoryTeller 所指出的,如果您在 List&lt;T&gt; 类的上下文中,则可以只使用 Node。您可以通过使用尾随返回类型来获取此上下文:

template <typename T>
auto List<T>::find(T val) -> Node *

【讨论】:

  • auto List&lt;T&gt;::find(T) -&gt; Node*。我自己觉得眼睛不那么痛了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多