iOS - GCC не видит функцию, которая кажется явно видимой - PullRequest
1 голос
/ 23 сентября 2011

Эта проблема может быть прямым результатом того, что я неправильно понял ограничения Objective-C (++) и то, как он взаимодействует с C ++. Или это может быть случай, когда я что-то упустил прямо передо мной.

У меня есть класс C ++, который выполняет некоторые задачи Objective-C ++ за кулисами. Таким образом, у меня есть шаблонный класс C ++, который делает вызов шаблонной функции. Затем я специализировал шаблонную функцию для создания UIImage.

Однако при сборке я получаю следующую ошибку.

../ImageProcessing/ImageProcessing/MacOS/MacOSImage.h:43: error: no matching function for call to 'MacOSImage<R5G5B5A1>::MakeUIImage(std::vector<R5G5B5A1, std::allocator<R5G5B5A1> >&, unsigned int, unsigned int)'
../ImageProcessing/ImageProcessing/MacOS/MacOSImage.h:41: note: candidates are: UIImage* MacOSImage<ColourSpace>::MakeUIImage() [with ColourSpace = R5G5B5A1]

Мой заголовочный файл выглядит так:

#ifndef ImageProcessing_MacOSImage_h
#define ImageProcessing_MacOSImage_h

#include "Image.h"

#ifdef __OBJC__
    #import <UIKit/UIImage.h>
#else
    typedef void UIImage;
#endif

template< typename ColourSpace > UIImage* MakeUIImage( const std::vector< ColourSpace >& colours, unsigned int width, unsigned int height )
{
    return NULL;
}

template< typename ColourSpace > class MacOSImage : public BaseImage< ColourSpace >
{
protected:

public:
    MacOSImage( unsigned int width, unsigned int height );
    virtual ~MacOSImage()   {};

    UIImage* MakeUIImage();
};

template< typename ColourSpace > inline MacOSImage< ColourSpace >::MacOSImage( unsigned int width, unsigned int height ) :
    BaseImage< ColourSpace >( width, height )
{
}

template< typename ColourSpace > inline UIImage* MacOSImage< ColourSpace >::MakeUIImage()
{
    return MakeUIImage( BaseImage< ColourSpace >::Pixels(), BaseImage< ColourSpace >::GetWidth(), BaseImage< ColourSpace >::GetHeight() );
}

#endif

Я нахожу эту ошибку довольно запутанной. Не в последнюю очередь потому, что если вы игнорируете мою специализацию, есть функция шаблона, которая должна точно соответствовать прототипу, после которого она находится вверху файла. Единственным недостатком является то, что он вернет NULL. Однако это все равно дало бы мне представление о том, что происходит, если бы я мог заставить его скомпилироваться.

Так у кого-нибудь есть идеи, почему это не скомпилируется?

Ура!

Редактировать : В соответствии с просьбой, это Image.h:

#ifndef ImageProcessing_Image_h
#define ImageProcessing_Image_h

#include <vector>

template< typename ColourSpace > class BaseImage
{
protected:
    unsigned int                mWidth;
    unsigned int                mHeight;
    std::vector< ColourSpace >  mPixels;
public:
    BaseImage( unsigned int width, unsigned int height );
    virtual ~BaseImage()        {};

    std::vector< ColourSpace >& Pixels();
    const std::vector< ColourSpace >& Pixels() const;

    unsigned int GetWidth() const               { return mWidth;    }
    unsigned int GetHeight() const              { return mHeight;   }
    unsigned int GetBytesPerPixel() const       { return sizeof( ColourSpace );     }
    unsigned int GetBitsPerPixel() const        { return GetBytesPerPixel() * 8;    }
};

template< typename ColourSpace > inline BaseImage< ColourSpace >::BaseImage( unsigned int width, unsigned int height )  :
    mWidth( width ),
    mHeight( height ),
    mPixels( width * height )
{

}

template< typename ColourSpace > inline std::vector< ColourSpace >& BaseImage< ColourSpace >::Pixels()
{
    return mPixels;
}

template< typename ColourSpace > inline const std::vector< ColourSpace >& BaseImage< ColourSpace >::Pixels() const
{
    return mPixels;
}

#if     defined( _OSX )

#include "MacOS/MacOSImage.h"
#define Image MacOSImage

#elif   defined( _WIN32 )

#include "Win32/Win32Image.h"
typedef Win32Image Image;

#else

#error We need a platform specific implementation of the image class

#endif

#endif

1 Ответ

3 голосов
/ 23 сентября 2011

Это классическая проблема поиска имени.Компилятор прекращает поиск имен, когда находит функцию с тем же именем, игнорируя подпись.Только тогда он проверяет подпись и обнаруживает, что она не совпадает.

Вы хотите вызвать бесплатную версию, поэтому вам нужно сказать:

return ::MakeUIImage( BaseImage< ColourSpace >::Pixels(), 
BaseImage< ColourSpace >::GetWidth(), BaseImage< ColourSpace >::GetHeight() );

Несовместимый намек: лучше положить все свои вещив ваше собственное пространство имен, иначе вы можете рано или поздно столкнуться с сопутствующими трудностями, когда Everythign находится в глобальном пространстве имен

...