2011-12-25 110 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 2011-12-25 13:41:41

+0

以下劃線和大寫字母開頭的名字是保留的,請勿使用它們。此外,你錯過了重要的信息:*你怎麼稱呼那個功能?*什麼參數? – Xeo 2011-12-25 13:42:55

+0

大家知道,任何地方都包含雙下劃線的名字,只是以下劃線和大寫字母開頭的名字而已。 – Xeo 2011-12-25 13:54:32

回答

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++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改變的措辭,並允許具有內部鏈接的功能現在也:

(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++也允許內部鏈接。 – 2011-12-25 14:17:27

+0

@Johannes:我剛剛編輯過。 – Xeo 2011-12-25 14:18:31

+0

啊。我不知道這是爲什麼。這個構造的全部目的是編譯器有機會內聯函數。 – Albert 2011-12-25 14:36:48