I am trying to create an instance of a singleton class inside of a wrapper in a multithreaded environment. I am using the wrapper to ease my work and not to write multiple times Lock and Unlock in ManagerSources.
#define ManagerSOURCES() ManagerSources::GetInstance()
// Singleton
class ManagerSources :public Mutex {
protected:
std::map< std::string , SourcesSPtr > Objects;
static ManagerSources * Instance; // declared in a cpp file
ManagerSources() {}
ManagerSources( const ManagerSources& cpy ) {}
ManagerSources operator=( ManagerSources& cpy) {}
public:
static ManagerSources* GetInstance() {
if ( Instance == NULL )
Instance = new ManagerSources();
return Instance;
}
...
};
// This class is a wrapper for ManagerSources in a thread programming environment
template <class T>
class SingletonThreadSafe {
protected:
T *pointer;
public:
class proxy {
T* pointer;
public:
proxy(T* _pointer) : pointer(_pointer) {
// LOCK();
}
~proxy(){
// UNLOCK();
}
T* operator->() {
return pointer;
}
};
// Default parameter is needed for containers (eg. insert into a map) where we need
// a constructor without parameters
SingletonThreadSafe(T* cpy = NULL ): pointer(cpy) {
}
~SingletonThreadSafe() {
}
SingletonThreadSafe(const SingletonThreadSafe & cpy) {
this->pointer = cpy.pointer;
}
SingletonThreadSafe operator=(SingletonThreadSafe cpy) {
this->pointer = cpy.pointer;
return *this;
}
T operator*() {
return *pointer;
}
proxy operator->() {
return proxy( pointer );
}
};
I have the following declaration
typedef SingletonThreadSafe<ManagerSources> aa;
aa( ManagerSources::GetInstance() ); // doesn't work
or
aa( ManagerSOURCES() ); // the same as above; still not working
The syntax doesn’t work and it gives me the following error “Definition or redeclaration of ‘GetInstance’ not allowed inside a function”. And, I don’t know why. Any ideas of how I can resolve this?
Also, the strange fact for me is if I rewrite the constructor with the default parameter to
SingletonThreadSafe(T* cpy = T::GetInstace() ): pointer(cpy) {
}
the following declaration works
aa()->A_Function(A_Parameter);
And if I declare it still works
aa bb( ManagerSOURCES() ); // it works
( SmartPtr<ManagerSources>() = ManagerSOURCES() )->A_Function(A_Parameter); // it works;
// the constructor with the default parameter is called
I don’t know why I get the error “Definition or redeclaration of ‘GetInstance’ not allowed inside a function “.
I am using Xcode 4.4.1 and LLVM GCC 4.2 compiler.
This is a variant of the most vexing parse.
is interpreted as a declaration of a function
ManagerSources::GetInstancetaking no parameters and returning typeaa.You can work around it with a
static_cast:A cast to
voidwould also work, as would anything else that prevents the expression being parsed as a declaration: