0

I am trying to build someone else's code in VS2010. It builds fine in VS2005, but I need to upgrade it.

They have defined a macro as follows in a header:

#include <boost/scoped_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/thread/once.hpp>

#define DEFINE_SINGLETON(name) boost::scoped_ptr<name> Singleton<name>::_instance

template<class T> class Singleton : private boost::noncopyable
{
    public:
        static T& instance() 
        {
            boost::call_once(init, flag);        
            return *_instance;
        }

        static void init()  
        {
            _instance.reset(new T());
        }

    protected:
        Singleton() {}
        ~Singleton() {}

    private:
        static boost::scoped_ptr<T> _instance;
        static boost::once_flag flag;
};

template<class T> boost::once_flag Singleton<T>::flag = BOOST_ONCE_INIT;

I've managed to get the code to build now, but I am getting lots of linker errors about this macro:

project1.lib(file1.obj) : error LNK2001: unresolved external symbol "private: static class boost::scoped_ptr<class ClassABC> Singleton<class ClassABC>::_instance" (?_instance@?$Singleton@VClassABC@@@@0V?$scoped_ptr@VClassABC@@@boost@@A)

An example of the macro being used (in source file):

#include "singleton.h"
DEFINE_SINGLETON(ClassABC);

I am quite new to Boost and also to templates (sorry), so I cannot fathom why I'm getting these errors when it all linked fine in VS2005. Its worth noting, that in order to do the upgrade we have also had to upgrade our Boost version, so this could be a factor - a few checks already performed:

  • Header file is included in source file
  • Boost dir is added to include dirs (under VC++ dirs inproperty pages)
  • Added boost lib dir to Linker -> General -> Additional library dependencies

For info, I am compiling a Multi-threaded debug dll on Win32.

I have spent most of the day googling to no avail, so any help greatly appreciated!

Many thanks :)

namford
  • 1,171
  • 1
  • 14
  • 13

1 Answers1

0

I don't see you used the macro anywhere in the posted code.

You need to use it as:

//add this line after BOOST_ONCE_INIT or before it, or wherever you see fit.
template<class T> DEFINE_SINGLETON(T);

Personally I would prefer this:

template<class T> boost::scoped_ptr<T> Singleton<T>::_instance;
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Sorry, have now included example of macro being used – namford May 23 '12 at 14:46
  • Thank you, but the code was like this in VS2005 and the macro call is used like this (without the type) all over the code and worked fine in VS2005...why would it be different in VS2010? – namford May 23 '12 at 14:48
  • I changed the code to have a type like you suggested but it made no difference...same linker errors. Any other suggestions as to what might be causing them? – namford May 23 '12 at 14:57
  • @namford: Do that in the header file itself. Template definitions should be present in the header itself. – Nawaz May 23 '12 at 15:00
  • Where? I am new to templates, so if you could actually type out the change you propse that would make it a lot clearer for me. Thank you! – namford May 23 '12 at 15:03
  • @namford: in the header file itself, after the definition of the class template, where you've written `BOOST_ONCE_INIT` thing. – Nawaz May 23 '12 at 15:17
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/11651/discussion-between-namford-and-nawaz) – namford May 23 '12 at 15:37