未定义的引用与嵌套的类模板静态const成员

时间:2015-12-01 00:48:14

标签: c++ templates linker linker-errors static-members

我有类似的东西,由其他3个类(列表,队列,堆栈......)继承:

template <typename generic>
class singlyLinkedList
{
    protected:

    class innerNode
    {
        public:

        innerNode *NextNode;
        generic Value;

        innerNode( generic value, innerNode *next = NULL ) :
            NextNode(next), Value(value) {}
    };

    innerNode *FirstNode;
    innerNode *LastNode;

    size_t CurrentSize;

    public:

    class iterator
    {
        private:

        innerNode *InnerNode;
        const bool IsDeepCopy;

        static const innerNode DefaultNode;

        public:

        iterator( innerNode *node = NULL ) : InnerNode(node), IsDeepCopy(false)
        {
            if (node == NULL) 
                this->InnerNode = (innerNode*)(&(iterator::DefaultNode));
        }

        iterator( innerNode *node, bool deepCopy ) : IsDeepCopy(deepCopy)
        {
            if (deepCopy) this->InnerNode = new innerNode(node->Value, node->NextNode);
            else this->InnerNode = node;
        }

        ~iterator()
        {
            if (this->IsDeepCopy) delete this->InnerNode;
        }

        inline bool isNull() const
        {
            return (this->InnerNode != &(iterator::DefaultNode));
        }

        // ...other iterator members which doesn't use the static member
    };

    // ...other singlyLinkedList members, some returning iterators
};

我曾经有一个单独的singlyLinkedNode类作为节点和迭代器,使用友谊来提供对列表类的特殊访问......然后我决定将所有内容更改为如何现在(如上一节)。

由于iterator嵌套在类模板中,据我所知,可以在头文件中定义类模板的静态const成员,我没有理由得到 Undefined来自此代码的链接器的引用错误。但是,我得到了这个:

/tmp/cc6vtGDj.o: In function `basicSinglyLinkedList<double>::iterator::iterator(basicSinglyLinkedList<double>::innerNode*)':
oo_test.cpp:(.text._ZN21basicSinglyLinkedListIdE8iteratorC2EPNS0_9innerNodeE[_ZN21basicSinglyLinkedListIdE8iteratorC5EPNS0_9innerNodeE]+0x2d): undefined reference to `basicSinglyLinkedList<double>::iterator::DefaultNode'
/tmp/cc6vtGDj.o: In function `basicBinarySearchTree<int>::iterator::iterator(basicBinarySearchTree<int>::innerNode*)':
oo_test.cpp:(.text._ZN21basicBinarySearchTreeIiE8iteratorC2EPNS0_9innerNodeE[_ZN21basicBinarySearchTreeIiE8iteratorC5EPNS0_9innerNodeE]+0x2a): undefined reference to `basicBinarySearchTree<int>::DefaultNode'
collect2: error: ld returned 1 exit status
Compilation failed.

有人可以解释一下我为什么会收到singlyLinkedList<>::iterator::DefaultNode的链接器错误或者...我有什么选择来设置一个&#34;默认节点&#34;控制无效的迭代器以及它们指向的位置?

1 个答案:

答案 0 :(得分:2)

在标头中定义模板类的静态const成员是完全正确的。但重点是你必须定义它 - 你只在这里声明它。

在课程定义之外,您应该添加

template <typename T>
singlyLinkedList::innerNode singlyLinkedList::iterator::defaultNode = T();

(或类似的东西)初始化存储,就像在常规类的静态成员的实现文件中那样。链接器将在最终的可执行文件中将所有模板化静态变量合并在一起,就像模板函数一样。

编辑:

以上是我的头脑:更多地考虑定义需要更像

template <typename T>
const typename singlyLinkedList<T>::innerNode singlyLinkedList<T>::iterator::defaultNode = T{};

但我现在无法尝试。不过,编译器应该指导它实际想要你说的内容。