简体   繁体   English

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

[英]Undefined reference vs. nested class template static const member

I have something like this, which is inherited by other 3 classes (list, queue, stack...): 我有类似的东西,它是由其他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
};

I used to have a separate singlyLinkedNode class to serve both as node and iterator, using friendships to give special access to the list classes... Then I've decided I'd change everything to how it is now (as in the above section). 我曾经有一个单独的singlyLinkedNode类既可以用作节点又可以用作迭代器,使用友谊可以对列表类进行特殊访问...然后,我决定将所有内容更改为现在的样子(如上一节所述) )。

Since iterator is nested in a class template and, as far as I know, it's possible to define static const members of class templates in headers, I saw no reasons to get Undefined Reference error from the linker for this code. 由于iterator嵌套在类模板中,据我所知,可以在标头中定义类模板的静态const成员,因此我没有理由从链接器获取此代码的未定义引用错误。 However, I'm getting this: 但是,我得到这个:

/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.

Can somebody explain me why am I getting a linker error for singlyLinkedList<>::iterator::DefaultNode OR... what alternatives do I have to set a "default node" to control invalid iterators and where they point to? 有人可以解释一下为什么为什么我收到singlyLinkedList<>::iterator::DefaultNode的链接器错误,或者...我必须设置“默认节点”来控制无效的迭代器以及它们指向何处?

It's perfectly fine to define a static const member of a template class in a header. 在标头中定义模板类的静态const成员非常好。 But the point is you have to define it -- you have only declared it here. 但是关键是您必须定义它-您只在这里声明了它。

Outside the class definition, you should add 在类定义之外,您应该添加

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

(or something similar) to initialise the storage, like you would in an implementation file for a static member of a regular class. (或类似方式)初始化存储,就像在实现文件中使用常规类的静态成员一样。 The linker will take care of merging all the templated static variables together in the final executable, as it does for template functions. 链接器将负责将所有模板化的静态变量合并到最终的可执行文件中,就像模板功能一样。

EDIT: 编辑:

The above was off the top of my head: having given it a bit more thought the definition will need to be more like 以上是我的头等大事:多给了一点想法,定义将需要更像

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

but I can't try it right now. 但我现在无法尝试。 The compiler should guide towards what it actually wants you to say, though. 但是,编译器应指导您实际要说的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM