【问题标题】:Good way to template a class/struct combination模板类/结构组合的好方法
【发布时间】:2015-01-08 19:20:55
【问题描述】:

模板化类的最有效方法是调用模板化结构。这是模板的经典有序列表问题。到目前为止,我的整个有序列表都有效(当我只是手动更改类型时)。但是,我不确定如何模板化这对对象(结构和类)。

所以基本上,这是我的代码的结构:

struct Node {
    int* data;
    Node* next;
};

class OList {
    private:
        Node* start;
        int size;
    public:
        a bunch of manipulation functions
};

所以,我的愿望是简单地将结构模板化,然后接受将模板传递给 Node 结构类型的参数。但是,我的第一次尝试是:

template<class T> 

在 Node 结构之前并将所有 ints* 更改为 T* 失败了。根据任何人的经验,什么可能是更好的方法?任何人都可以指出我正确的方向或给我一些模板基础知识的好参考吗?我只能找到一些具体的问题,这并不能让我很好地了解模板的工作原理。

更新:我的代码在这一点上运行良好。我唯一不明白的是如何在函数中返回 Node 结构的指针。例如,在一个函数中,

template <class T>
List<T>::Node<T>* List<T>pos(int val); //trying to return a pointer to the node at a specified spot

我收到以下错误:“Non-templated 'Node' used as template。注意:使用 OList::template Node' 表示它是一个模板 (???) 错误:需要 'typename' 在 'OList ::Node',因为'OList 是一个依赖范围“清除这些错误的最有效方法是什么?注释掉这一功能时,代码可以完美运行。

【问题讨论】:

  • 请在模板化后包含NodeOList的声明。
  • "failed miserably" 甚至无法充分描述问题...您是否也将OList 设为模板?还是只是Node"?
  • 我不确定这是否是一个好习惯或可能,但您可以将 Node 类放在 OList 类中并从那里开始?
  • 我做了两个模板

标签: c++ class templates struct


【解决方案1】:
template <typename T>     // <----
struct Node {
    T* data;              // <----
    Node* next;
};

template <typename T>     // <----
class OList {
    private:
        Node<T>* start;   // <----
        int size;
    public:
        a bunch of manipulation functions
};

或者...

template <typename T>
class OList {
    private:
        typedef ::Node<T> Node;  // <---- just do it once
        Node* start;   

...或者按照 BWG 评论中的建议,直接在OList 中定义Node,因此所有&lt;T&gt; 方面都是隐式的...

template <typename T>
class OList {
    private:
        struct Node { T* data; int size; };  // <----
        Node* start;   

外联成员函数定义示例:

template <typename T>
class OList
{
    private:
        struct Node { T* data; };
        Node* f(Node*);
    public:
};

template <typename T>
typename OList<T>::Node* OList<T>::f(typename OList<T>::Node* p)   // see notes
{
    Node* p2 = p;    // can use Node as if inside class definition
    return p2;
}

注意丑陋的线条...

typename OList<T>::Node* OList<T>::f(typename OList<T>::Node* p)
' T'),并且我们需要不断提及NodeQList 的范围内,以及要在其中找到它的QList 的特定实例化是基于模板参数T。都是有道理的,就是有点迂腐。

至于模板的一般工作方式,对于 Stack Overflow 上的答案来说,这可以说是“过于宽泛”,但 FWIW 可能是快速开始对此进行一些实际理解的最快方法(之后需要一些改进),是通过比较他们到宏。考虑:

#define NODE(T)      \
struct Node ## T {   \
    T* data;         \
    Node ## T* next; \
};

有了这个,你可以说NODE(int)NODE(float) 来为这些类型生成Node_intNode_float 结构。使用模板,您(通常)不需要单独定义每个特化 - 它在使用时隐式完成(“参数多态性”) - 所以只需开始将它们用于变量ala Node&lt;int&gt; my_node_for_ints。 p>

【讨论】:

  • 所以我可以将整个结构与 OList 的类定义放在一起?这会让事情变得更容易,因为那时我只需要做模板其中一个而不是两个
  • 另外,在.h文件的声明下面的函数中,如何指定类型T?例如,我有一些函数接受给定类类型的输入,然后对它们执行类定义中指定的函数。有关我正在讨论的内容,请参见上面的示例代码。
  • @Eric - “将整个结构放入类中” - 是的,当然......如果Node 没有用于其他(容器)类型的实现,那么这样封装会更好。 ...
  • 啊,好吧。这是有道理的,因为 Node 仅在类定义的上下文中使用。感谢你的帮助;我真的很感激!
  • @Eric 在类定义之后重新定义成员函数...我在答案中添加了一个示例。
【解决方案2】:

你的意思是这样的:

template <typename T>
struct Node {
    T data;
    Node* next;
};

template <typename T>
class OList {
    private:
        Node<T> start;
        int size;
    public:
};

?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多