【问题标题】:Undefined reference vs. nested class template static const member未定义引用与嵌套类模板静态 const 成员
【发布时间】:2015-12-01 00:48:14
【问题描述】:

我有这样的东西,它被其他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 Reference 错误来自此代码的链接器。但是,我得到了这个:

/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&lt;&gt;::iterator::DefaultNode 的链接器错误或者...我必须设置“默认节点”来控制无效迭代器及其指向的位置吗?

【问题讨论】:

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


    【解决方案1】:

    在标头中定义模板类的静态 const 成员非常好。但关键是你必须定义它——你只在这里声明了它。

    在类定义之外,你应该添加

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

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

    编辑:

    上面的内容让我想不通:仔细考虑后,定义需要更像

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

    但我现在不能尝试。不过,编译器应该引导它真正想要你说什么。

    【讨论】:

    • 然后我得到类似:error: conflicting declaration ‘basicSinglyLinkedList&lt;generic&gt;::innerNode basicSinglyLinkedList&lt;generic&gt;::iterator::DefaultNode’error: ‘basicSinglyLinkedList&lt;generic&gt;::iterator::DefaultNode’ has a previous declaration as ‘const basicSinglyLinkedList&lt;generic&gt;::innerNode basicSinglyLinkedList&lt;generic&gt;::iterator::DefaultNode’
    • @PedroVernetti 是的,我忘记了 const 和模板参数。如果你想再试一次,我已经编辑了我的答案?
    • 是的..在看到您的更新之前,我对您的第一个代码进行了其他必要的更改...实际上,在发布问题之前我已经尝试过...整个问题是缺少@987654326 @.
    猜你喜欢
    • 1970-01-01
    • 2012-12-13
    • 2017-01-15
    • 1970-01-01
    • 2017-10-20
    • 2023-03-31
    • 1970-01-01
    • 2014-02-17
    相关资源
    最近更新 更多