I am porting a very large code base and I am having more difficulty with old code.
For example, this causes a compiler error:
inline CP_M_ReferenceCounted *
FrAssignRef(CP_M_ReferenceCounted * & to, CP_M_ReferenceCounted * from)
{
if (from) from->AddReference();
if (to) to->RemoveReference();
to = from;
return to;
}
The error is: error: expected initializer before '*' token.
How do I know what this is. I looked up inline member functions to be sure I understood and I dont think the inlining is the cause but I am not sure what is.
Another example:
template <class eachClass>
eachClass FrReferenceIfClass(FxRC * ptr)
{
eachClass getObject = dynamic_cast<eachClass>(ptr);
if (getObject) getObject->AddReference();
return getObject;
}
The error is: error: template declaration of 'eachClass FrReferenceIfClass'
That is all. How do I decide what this is?. I am admittedly rusty with templates.
UPDATE:
Here is CP_M_ReferenceCounted:
#pragma once
#ifndef _H_CP_M_RefCounted
#define _H_CP_M_RefCounted
// CPLAT_Framework
#include "CP_Types.h"
CPLAT_Begin_Namespace_CPLAT
/*!
* @class CP_M_RefCounted
* @brief Mix-in class for objects that are reference counted.
*/
class CP_EXPORT CP_M_RefCounted
{
public:
//! @name Reference
//@{
UInt32 AddReference() const;
UInt32 RemoveReference() const;
//@}
//! @name Autorelease
//@{
void Autorelease() const;
//@}
//! @name Getters
//@{
/*!
* Returns the current ref count.
*
* @exception none
*
* @return UInt32 The current referencce count.
*/
UInt32 GetRefCount() const { return( fRefCount ); }
//@}
//! @name operators
//@{
CP_M_RefCounted& operator = ( const CP_M_RefCounted& inRefCounted );
//@}
protected:
//! @name Constructor / Destructor
//@{
//! Constructor.
CP_M_RefCounted();
CP_M_RefCounted( CP_M_RefCounted& inRefCounted );
//! Destructor.
virtual ~CP_M_RefCounted();
//@}
// class data
private:
mutable UInt32 fRefCount; /*! The number of references to this object. */
//========================================================================
// Platform specific routines
//========================================================================
#if TARGET_OS_MAC
#endif
#if TARGET_OS_WIN32
#endif
#if TARGET_OS_LINUX
#endif
};
template <class T>
inline const T* CP_Autorelease(const T* inObj)
{
if( inObj )
inObj->Autorelease();
return( inObj );
}
template <class T>
inline T* CP_Autorelease(T* inObj)
{
if( inObj )
inObj->Autorelease();
return( inObj );
}
/*!
* @class CP_SmartRef
* @brief Template class representing a smart pointer for reference counted objects.
*/
template <class T>
class CP_SmartRef
{
public:
//! @name Constructor / Destructor
//@{
//! Constructor.
CP_SmartRef()
: fObj(NULL) {}
CP_SmartRef(
T *inObj,
bool inTransferOwnership=false )
: fObj(inObj) { if( !inTransferOwnership && fObj ) fObj->AddReference(); }
CP_SmartRef( const CP_SmartRef<T>& inRef )
: fObj(inRef.fObj) { if( fObj ) fObj->AddReference(); }
template <class Other>
CP_SmartRef( const CP_SmartRef<Other>& inRef )
: fObj(NULL) { T* other = inRef.Get(); this->Reset( other ); } // assignment to local variable should prevent upcasts and cross-casts
//! Destructor.
~CP_SmartRef() { if( fObj ) fObj->RemoveReference(); }
//@}
//! @name operators
//@{
T& operator *() const { return( *fObj ); }
T* operator->() const { return( fObj ); }
operator T *() const { return( fObj ); }
CP_SmartRef<T>& operator = ( const CP_SmartRef<T>& inRef ) { this->Reset( inRef.fObj ); return *this; }
template <class Other>
CP_SmartRef<T>& operator = ( const CP_SmartRef<Other>& inRef ) { this->Reset( inRef.Get() ); return *this; }
CP_SmartRef<T>& operator = ( T* inObj ) 开发者_运维百科 { this->Reset( inObj ); return *this; }
template <class Other>
CP_SmartRef<T>& operator = ( Other* inObj ) { this->Reset( inObj ); return *this; }
//@}
//! @name Object management
//@{
T *Get() const { return( fObj ); }
T *Reset(
T *inObj,
bool inTransferOwnership = false );
T *Release();
//@}
// class data
protected:
T *fObj;
//========================================================================
// Platform specific routines
//========================================================================
#if TARGET_OS_MAC
#endif
#if TARGET_OS_WIN32
#endif
#if TARGET_OS_LINUX
#endif
};
template <class T>
T* CP_SmartRef<T>::Reset( T *inObj, bool inTransferOwnership )
{
if ( inObj != fObj )
{
if( fObj )
fObj->RemoveReference();
fObj = inObj;
if( inObj && !inTransferOwnership )
inObj->AddReference();
}
else if( inObj && inTransferOwnership )
{
inObj->RemoveReference();
}
return( fObj );
}
template <class T>
T* CP_SmartRef<T>::Release()
{
T *tmp = fObj;
fObj = NULL;
return( tmp );
}
CPLAT_End_Namespace_CPLAT
#endif // _H_CP_M_RefCounted
I think you have to develop some kind of feeling for the error messages of your compiler. There are worse and there are better compilers. That one is surely one of the worse. A good one points the caret to the place where the error occurs and gives hint what could be wrong.
For example in the given case, the compiler probably stops parsing the type of the declaration when it reaches CP_M_ReferenceCounted
and parses it as the name of what is to be declared. The grammar allows that, because some declarations are not given a type (constructors are an example). So it expects an initializer for that name, and not a star. This hints that CP_M_ReferenceCounted
probably isn't declared. Check you included the correct header.
Others are addressing your specific errors, so I'll try addressing the big picture.
One of the goals of the Clang project is to have more helpful diagnostics. Clang's C++ support is incomplete, but depending on how much your code pushes the boundaries of the C++ language, it may be enough to give you good error messages.
For templates in the STL, try using STLFilt. I've used it several times, and it does a wonderful job of cleaning up multi-line error messages, cluttered with default template parameters, and replacing them with something understandable. I'm not sure how much it does for templates outside of the STL, but it might be worth a try.
I won't answer your "big picture" question, but your first error looks simple enough.
In the first snippet, my guess is that the CP_M_ReferenceCounted
class hasn't been declared. You probably forgot to include "CP_M_ReferenceCounted.h" or some similarly named file. The compiler is telling you that it hasn't found a type name to which it can apply the the * (pointer) modifier, meaning that it doesn't recognize CP_M_ReferenceCounted as a valid type name. That implies that the declaration is missing, which in turn likely implies a missing header file include.
The second error is admittedly a mystery to me. I'd use "typename" instead of class since you're using eachClass as a pointer, but that shouldn't technically make any difference even if it would add clarity.
You've shown us some problem code using CP_M_ReferenceCounted
, but shown us the header file for CP_M_RefCounted
. That looks like the wrong header or you've misspelt the class name.
Also, don't use leading underscores in you header include guards. Capitalisation and underscores-instead-of-spaces is OK: H_CP_M_RefCounted
or H_CP_M_REFCOUNTED
or CP_M_REFCOUNTED_H
精彩评论