2011-12-25 12 views
4

に無効な明示的に指定された引数:C++:候補テンプレート無視:私はこの機能ヘッダーを持つテンプレートパラメータ

template < 
    bool src_alpha, 
    int sbpp, int dbpp, 
    typename T1, typename T2, 
    Color (*getFunc)(T1 data, Uint8* addr), 
    void (*putFunc)(T2 data, Uint8* addr, Color c) 
> 
static void OperateOnSurfaces(T1 data1, T2 data2, SDL_Surface * bmpDest, SDL_Surface * bmpSrc, SDL_Rect& rDest, SDL_Rect& rSrc) 

これは私がそれを使用する方法です:

OperateOnSurfaces< 
    true, 
    32, 32, 
    SDL_PixelFormat*, SDL_PixelFormat*, 
    GetPixel<true,32>, PutPixel<true,true,32> >(
    bmpSrc->format, bmpDest->format, 
    bmpDest, bmpSrc, rDest, rSrc); 

これはGetPixelPutPixel次のとおりです。

template<bool alpha, int bpp> 
static Color GetPixel(SDL_PixelFormat* format, Uint8* addr) { /* .. */ } 

template<bool alpha, bool alphablend, int bpp> 
static void PutPixel(SDL_PixelFormat* format, Uint8* addr, Color col) { /* .. */ } 

そして、このエラーが発生します:

note: candidate template ignored: invalid explicitly-specified argument for template parameter 'getFunc' [3]

なぜですか?

+0

どのように使用しますか? – kennytm

+0

アンダースコアと大文字で始まる名前は予約されています。使用しないでください。また、あなたは重要な情報が欠落しています:*どのようにあなたはその関数を呼び出しますか?*どのようなパラメータ? – Xeo

+0

二重アンダースコアを含む名前は、アンダースコアと大文字で始まる名前と同様に予約されています。 – Xeo

答えて

6

これらの機能はすべて無料の機能と考えられます。自由な関数staticを宣言すると、内部リンケージが得られます。 C++の03以外のテンプレートパラメータでは、に外部リンクが必要です。機能の前でstaticを削除するだけです。

template < 
    bool src_alpha, 
    int sbpp, int dbpp, 
    typename T1, typename T2, 
    char (*getFunc)(T1 data, unsigned* addr), 
    void (*putFunc)(T2 data, unsigned* addr, char c) 
> 
void OperateOnSurfaces(){} 

template<bool alpha, int bpp> 
char GetPixel(void* format, unsigned* addr); 

template<bool alpha, bool alphablend, int bpp> 
void PutPixel(void* format, unsigned* addr, char col); 

int main(){ 
    OperateOnSurfaces< 
     true, 
     32, 32, 
     void*, void*, 
     GetPixel<true,32>, PutPixel<true,true,32> >(); 
} 

本変形例では、C++ 98とC++ 11モード、警告なしにクラン3.1とGCC 4.4.5に細かいコンパイル。私はstaticを残す場合は、(右にスクロールし、「外部結合はしていない」)私はあなたがクランで得たものと同様のエラー+ノートを取得し、GCCは、重要な情報を出してくれる:

15:02:38 $ g++ t.cpp 
t.cpp: In function ‘int main()’: 
t.cpp:21: error: ‘GetPixel<true, 32>’ is not a valid template argument for type ‘char (*)(void*, unsigned int*)’ because function ‘char GetPixel(void*, unsigned int*) [with bool alpha = true, int bpp = 32]’ has not external linkage 
t.cpp:21: error: ‘PutPixel<true, true, 32>’ is not a valid template argument for type ‘void (*)(void*, unsigned int*, char)’ because function ‘void PutPixel(void*, unsigned int*, char) [with bool alpha = true, bool alphablend = true, int bpp = 32]’ has not external linkage 
t.cpp:21: error: no matching function for call to ‘OperateOnSurfaces()’ 

C++ 11は、文言を変更しすぎる今内部結合を持つ機能を可能(C++03) §14.3.2 [temp.arg.nontype] p1

A template-argument for a non-type, non-template template-parameter shall be one of:

  • [...]

  • the address of an object or function with external linkage [...]

  • [...]

注†:

(C++11) §14.3.2 [temp.arg.nontype] p1

A template-argument for a non-type, non-template template-parameter shall be one of:

  • [...]

  • a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage [...]

  • [...]

Clangは現在、C++ 11モードでこれに従っていませんが、それでも外部リンケージを持つ関数のみが許可されています。

+0

この回答はC++ 03のみに該当します。現在のC++では、内部リンケージも可能です。 –

+0

@Johannes:私はちょうどそれを編集しました。 – Xeo

+0

ああ。私はなぜそれが不思議です。この構文の全目的は、コンパイラが関数をインライン化する機会を持つことです。 – Albert

関連する問題