I don't think my question is a duplicate of this one.
what I try to do:
template<const char* szFunctionName> class CReentranceLock { public: CReentranceLock(){} ~CReentranceLock(){} bool isLocked(){return s_bLock;} void setLocked(bool b) { const bool Result=(bool)InterlockedCompareExchange( (unsigned long *)&s_bLock, b, !b); } private: static bool s_bLock; }; template<const char* szFunctionName> bool CReentranceLock<const char*szFunctionName>::s_bLock=false; // error C2146: syntax error : missing ',' before identifier 'szFunctionName' implying that all instances of CReentranceLock would have their own static, relying on the const char address of the function name passed as a parameter of the template.
and that could be used like this:
void CMyObject::InAnyFunction() { const char* szFunctionName = __FUNCTION__; CReentranceLock<szFunctionName> lock; // Edit: <- this doesn't work if(lock.isLocked()) return; lock.setLocked(true); /// business code lock.setLocked(false); } well that's only the theory... and unfortunately this doesn't compile under visual 2010, at the line where I try to initialize the statics.
error C2146: syntax error : missing ',' before identifier 'szFunctionName' what am I doing or thinking wrong ?
PS: and I am not dealing with the fact that reentrance is smelling like an awful design (in MFC), I know, I am lost in the middle of it ;-)
Edit: though the answer below is good, and the definition compiles... my use in CMyObject::InAnyFunction() with a const char * as a template-parameter available at compile time seems to be wrong. :-(
s_bLockitself does not exist unless you instance aCReentranceLock. theszFunctionNameis only a placeholder name that does not exist (as the compiler warns you). Tryconst char Foo[] = {"Foo"}; bool CReentranceLock<Foo>::s_bLock=false;instead. (but you will set only thes_bLockof theFooinstance type ofCReentranceLock).const char *is convertible to anint?