Question

I am writing an immutable binary search tree in c++. My terminating nodes are represented by a singleton empty node. My compiler (visual c++) seems to be having trouble resolving the protected static member that holds my singleton. I get the following error:

error LNK2001: unresolved external symbol "protected: static class boost::shared_ptr > node::m_empty" (?m_empty@?$node@HH@@1V?$shared_ptr@V?$node@HH@@@boost@@A)

I am assuming this means it cant resolve the static m_empty member for the type node. Is this correct? If so how do I fix it?

Code follows:

using namespace boost;
template<typename K, typename V>
class node {
protected:
    class empty_node : public node<K,V> {
    public:
        bool is_empty(){ return true; }
        const shared_ptr<K> key() { throw cant_access_key; }
        const shared_ptr<V> value()  { throw cant_access_value; }
        const shared_ptr<node<K,V>> left()  { throw cant_access_child; }
        const shared_ptr<node<K,V>> right()  { throw cant_access_child; }
        const shared_ptr<node<K,V>> add(const shared_ptr<K> &key, const shared_ptr<V> &value){
            return shared_ptr<node<K,V>>();
        }
        const shared_ptr<node<K,V>> remove(const shared_ptr<K> &key) { throw cant_remove; }
        const shared_ptr<node<K,V>> search(const shared_ptr<K> &key) { return shared_ptr<node<K,V>>(this); }
    };

    static shared_ptr<node<K,V>> m_empty;
public:
    virtual bool is_empty() = 0;
    virtual const shared_ptr<K> key() = 0;
    virtual const shared_ptr<V> value() = 0;
    virtual const shared_ptr<node<K,V>> left() = 0;
    virtual const shared_ptr<node<K,V>> right() = 0;
    virtual const shared_ptr<node<K,V>> add(const shared_ptr<K> &key, const shared_ptr<V> &value) = 0;
    virtual const shared_ptr<node<K,V>> remove(const shared_ptr<K> &key) = 0;
    virtual const shared_ptr<node<K,V>> search(const shared_ptr<K> &key) = 0;


    static shared_ptr<node<K,V>> empty() {
        if(m_empty.get() == NULL){
            m_empty.reset(new empty_node());
        }
        return m_empty;
    }
};

the root of my tree is initialized as:

shared_ptr<node<int,int>> root = node<int,int>::empty();
Was it helpful?

Solution

m_empty is static and so you'll need to have a source (.cpp) file with something like the following:

template <typename K, typename V> shared_ptr<node<K,V> > node<K,V>::m_empty;

Note: My original answer was incorrect and did not take into account that this was a template. This is the answer that AndreyT gave in his answer; I've updated this answer with the correct answer because this is the accepted answer and appears at the top of the page. Please upvote AndreyT's answer, not this one.

OTHER TIPS

As others said, you need to provide a definition point for your static member. However, since it is a member of a template, the syntax is going to be a bit more complex then what was suggested before. If I'm not missing anything, it should look as follows

template<typename K, typename V> shared_ptr<node<K,V> > node<K,V>::m_empty;

You can also provide an initializer (or initializers) in this declaration, if necessary.

You need to initialize the m_empty variable in your .cpp file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top