views:

91

answers:

2

I have a singleton library from a linux project that I'm trying to port to Windows. When I try to compile, it errors with

syntax error: identifier "rpSingleton"

The error is from the following section of code:

template <typename T> inline T& 
   Q::Singleton<T>::Instance()
   {
   Singleton<T>*& rp_singleton(rpSingleton()); //ERRORS HERE
   if (0 == rp_singleton)
      {
      rp_singleton = new Singleton<T>;
      }
   return rp_singleton->mInstance;
   }

Below is the whole file for reference. Any idea what's wrong?

#ifndef Q_SINGLETON_H
#define Q_SINGLETON_H

// SYSTEM INCLUDES

#include <boost/noncopyable.hpp>

// PROJECT INCLUDES

// LOCAL INCLUDES

#include "NonDerivable.h"

// NAMESPACES

namespace Q
{
   template <typename T> class Singleton;
}

// FORWARD REFERENCES

namespace Q
{
template <typename T> void InstanceCleanup();
}


template <typename T> class Q::Singleton 
   : private boost::noncopyable
   , private virtual Qf::NonDerivable
   {
   // FRIENDS

   // Allow only T specialization of Instance be a friend
   friend T& Instance<T>();

   // Allow only the T specialization of Instance be a friend
   friend void InstanceCleanup<T>();

   public:
   protected:
   private:
   /// The single object
   T mInstance;

   /// Wrapper method of a static pointer to support instance and clean up
   ///
   static Singleton<T>*& rpSingleton();

   /// Constructor is private, must use Instance Method to use the object
   ///
   Singleton();

   /// Get the Instance of the Singleton
   /// \return The Instance
   static T& Instance();

   /// A way to free this singleton's resources before program termination
   ///
   static void CleanUp();

   };

// INLINE METHODS

template <typename T> inline T& 
   Q::Singleton<T>::Instance()
   {
   Singleton<T>*& rp_singleton(rpSingleton());
   if (0 == rp_singleton)
      {
      rp_singleton = new Singleton<T>;
      }
   return rp_singleton->mInstance;
   }

template <typename T> inline void 
   Q::Singleton<T>::CleanUp()
   {
   delete rpSingleton();
   rpSingleton() = 0;
   }

template <typename T> inline Q::Singleton<T>*& 
   Q::Singleton<T>::rpSingleton()
   {
   static Singleton<T>* sp_singleton(0);
   return sp_singleton;
   }

template <typename T> inline Q::Singleton<T>::Singleton()
   {
   }

template <typename T> inline T& Q::Instance()
   {
   return Singleton<T>::Instance();
   }

template <typename T> inline void Q::InstanceCleanup()
   {
   Singleton<T>::CleanUp();
   }

// NON-INLINE METHODS (TEMPLATE CLASSES ONLY!!!!)

#endif // SINGLETON_H
A: 

Changing it to this:

Singleton<T>*& rp_singleton = rpSingleton();

Fixes it. But does that make any sense?

Adam Haile
+1  A: 

I think you're running into this from the C++ FAQ Lite. Basically, you're not actually initializing it. Personally, I'm surprised that the line in question is even LEGAL at all (my brain is melting at the reference-to-pointer), but take a look at the link. It shows how a compiler can interpret (or mis-interpret) certain kinds of initialization statements.

I THINK what you want to do is something like below:

Singleton<T>*& rp_singleton = rpSingleton();

So read the link. Basically I think the compiler is thinking you're calling a function, or something. Either way, the line about fixes it... I think.

Edit: you may also want to take a look at this section that deals with references.

Kevin
The syntax *should* be fine - the problem you point out should only arise if `rpSingleton` is a type name, which it isn't.
Mike Seymour