如何确定*真正*导致编译器错误的原因

问题描述 投票:0回答:4

我正在移植一个非常大的代码库,并且旧代码遇到更多困难。

例如,这会导致编译器错误:

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; 
}

错误是:错误:“*”标记之前需要初始化程序。

我怎么知道这是什么。我查找了内联成员函数以确保我理解,我不认为内联是原因,但我不确定是什么。

另一个例子:

template <class eachClass>
    eachClass FrReferenceIfClass(FxRC * ptr)
    {
        eachClass getObject = dynamic_cast<eachClass>(ptr);
        if (getObject)  getObject->AddReference();
        return getObject;
    }

错误是:错误:'eachClass FrReferenceIfClass'的模板声明

仅此而已。我如何决定这是什么?不可否认,我对模板已经生疏了。

更新:

这里是 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
c++ function templates
4个回答
3
投票

我认为你必须对编译器的错误消息产生某种感觉。有更差的编译器,也有更好的编译器。那肯定是最糟糕的之一。好的插入符号会将插入符号指向发生错误的位置,并提示可能出现的错误。

例如,在给定的情况下,编译器可能会在到达

CP_M_ReferenceCounted
时停止解析声明的类型,并将其解析为要声明的名称。语法允许这样做,因为某些声明没有给出类型(构造函数就是一个例子)。因此它需要该名称的初始值设定项,而不是星号。这暗示
CP_M_ReferenceCounted
可能没有声明。检查您是否包含了正确的标头。


2
投票

其他人正在解决您的具体错误,因此我将尝试解决大局问题。

Clang 项目的目标之一是提供更有用的诊断。 Clang 的 C++ 支持并不完整,但根据您的代码突破 C++ 语言界限的程度,它可能足以为您提供良好的错误消息。

对于 STL 中的模板,请尝试使用 STLFilt。 我已经使用过它好几次了,它在清理多行错误消息、混乱的默认模板参数以及用可理解的内容替换它们方面做得非常出色。 我不确定它对 STL 之外的模板有多大作用,但可能值得一试。


2
投票

我不会回答你的“大局”问题,但你的第一个错误看起来很简单。

在第一个片段中,我的猜测是

CP_M_ReferenceCounted
类尚未声明。 您可能忘记包含“CP_M_ReferenceCounted.h”或一些类似名称的文件。 编译器告诉您它尚未找到可以应用 *(指针)修饰符的类型名称,这意味着它无法将 CP_M_ReferenceCounted 识别为有效的类型名称。 这意味着缺少声明,这反过来又可能意味着缺少头文件包含。

第二个错误对我来说确实是个谜。 我会使用“typename”而不是类,因为您使用 everyClass 作为指针,但从技术上讲,即使它会增加清晰度,也不会有任何区别。


0
投票

您使用

CP_M_ReferenceCounted
向我们展示了一些问题代码,但向我们展示了
CP_M_RefCounted
的头文件。 这看起来像是错误的标题,或者您拼错了类名。

另外,不要在标头包含防护中使用前导下划线。 大写和下划线代替空格是可以的:

H_CP_M_RefCounted
H_CP_M_REFCOUNTED
CP_M_REFCOUNTED_H

© www.soinside.com 2019 - 2024. All rights reserved.