Как определить, что * действительно * вызывает вашу ошибку компилятора - PullRequest
3 голосов
/ 24 марта 2010

Я портирую очень большую кодовую базу, и у меня больше проблем со старым кодом.

Например, это вызывает ошибку компилятора:

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

Ошибка: error: объявление шаблона 'eachClass FrReferenceIfClass'

Это все. Как мне решить, что это? Я по общему признанию ржавый с шаблонами.

ОБНОВЛЕНИЕ:

Вот CP_M_ReferenceCounts:

#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

Ответы [ 4 ]

3 голосов
/ 24 марта 2010

Я думаю, вы должны развить какое-то чувство к сообщениям об ошибках вашего компилятора. Есть хуже и есть лучшие компиляторы. Этот, безусловно, один из худших. Хороший указывает на место, где происходит ошибка, и подсказывает, что может быть не так.

Например, в данном случае компилятор, вероятно, прекращает синтаксический анализ типа объявления, когда оно достигает CP_M_ReferenceCounted, и анализирует его как имя того, что должно быть объявлено. Грамматика позволяет это, потому что некоторые объявления не имеют типа (например, конструкторы). Так что ожидается инициализатор для этого имени, а не звезда. Это намекает на то, что CP_M_ReferenceCounted, вероятно, не объявлено. Убедитесь, что вы включили правильный заголовок.

2 голосов
/ 24 марта 2010

Другие исправляют ваши конкретные ошибки, поэтому я постараюсь исправить общую картину.

Одной из целей проекта Clang является предоставление более полезной диагностики . Поддержка Clang C ++ неполна, но в зависимости от того, насколько ваш код расширяет границы языка C ++, этого может быть достаточно, чтобы выдавать хорошие сообщения об ошибках.

Для шаблонов в STL попробуйте использовать STLFilt . Я использовал его несколько раз, и он прекрасно справляется с очисткой многострочных сообщений об ошибках, загроможденных параметрами шаблона по умолчанию, и заменяет их чем-то понятным. Я не уверен, сколько это стоит для шаблонов за пределами STL, но, возможно, стоит попробовать.

2 голосов
/ 24 марта 2010

Я не буду отвечать на ваш вопрос "большой картинки", но ваша первая ошибка выглядит достаточно просто.

В первом фрагменте я предполагаю, что класс CP_M_ReferenceCounted не был объявлен. Вы, вероятно, забыли включить «CP_M_ReferenceCounting.h» или файл с аналогичным именем. Компилятор сообщает вам, что он не нашел имя типа, к которому он может применить модификатор * (указатель), то есть он не распознает CP_M_ReferenceCounting как допустимое имя типа. Это означает, что декларация отсутствует, что, в свою очередь, скорее всего, означает, что отсутствующий заголовочный файл включает в себя.

Вторая ошибка, по общему признанию, для меня загадка. Я бы использовал «typename» вместо класса, поскольку вы используете каждый класс в качестве указателя, но технически это не должно иметь никакого значения, даже если это добавит ясности.

0 голосов
/ 24 марта 2010

Вы показали нам некоторый код проблемы, используя CP_M_ReferenceCounted, но показали нам файл заголовка для CP_M_RefCounted. Это выглядит как неправильный заголовок, или вы неправильно написали имя класса.

Кроме того, не используйте начальные подчеркивания в заголовке, включая охранники. С заглавными буквами и подчеркиванием вместо пробелов все в порядке: H_CP_M_RefCounted или H_CP_M_REFCOUNTED или CP_M_REFCOUNTED_H

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...