2010-02-03 53 views
0

我有這樣的模板:錯誤使用一個函數作爲非類型模板參數

 template <class SourceFormat, class DestFormat, void (*convert)(DestFormat, SourceFormat)> 
    static void _draw(...); 

而這些功能:

template <class Class1, class Class2> 
    inline static void convertNone(Class1& dest, Class2& source) { 
     dest = source; 
    }; 
    inline static void convertARGB_GREY(unsigned __int32& dest, unsigned __int8& source) { 
     dest = source + (source << 8); 
     dest += (dest << 16); 
    }; 

我使用模板的另一個功能:

void Blitter::draw(...) { 

    if (...) { 
     _draw<unsigned __int32, unsigned __int32, &convertNone>(...); 
    } else { 
     _draw<unsigned __int32, unsigned __int8, &convertARGB_GREY>(...); // ERRORS go here! 
    } 
} 

我得到這些錯誤:

Error 1 error C2440: 'specialization' : cannot convert from 'void (__cdecl *)(unsigned int &,unsigned char &)' to 'void (__cdecl *const)(unsigned char,unsigned int)' d:\projects\fanlib\source\blitter.cpp 102 
Error 2 error C2973: 'FANLib::Blitter::_draw' : invalid template argument 'void (__cdecl *)(unsigned int &,unsigned char &)' d:\projects\fanlib\source\blitter.cpp 102 

我想這是相當明顯的,我不完全理解的功能,作爲參數... :-(

提前

回答

2

我不知道你是否有意這樣做,但你的模板參數去源/ Destintaion然後目的地/來源。

注意,當你做你的_draw<unsigned __int32, unsigned __int8, &convertARGB_GREY>(...);模板定義填補他們爲:

SourceFormat = unsigned __int32
DestFormat = unsigned __int8
void (*convert)(unsigned __int8, unsigned __int32)

您沒有該定義的函數,雖然。

你有一個匹配 void (*convert)(unsigned __int32&, unsigned __int8&)
你怎麼看參數不匹配?

聲明模板是這樣的:

template < 
    class SourceFormat, 
    class DestFormat, 
    void (*convert)(SourceFormat, DestFormat)> 
static void _draw(...); 

和你的函數聲明是這樣的:

void convertARGB_GREY(
    unsigned __int32 source,  // notice how I removed the '&' 
    unsigned __int8 destination) // character on these two lines 

它將編譯。 (因爲你失去了參考,我建議在這種情況下返回結果:unsigned __int8 destination convertARGB_GREY(...)雖然)。

5

有在你的代碼的幾個問題非常感謝。

在你的代碼,當你調用_draw_draw模板的SourceFormatDestFormat參數與顯式參數提供。這些參數是純粹的非參考整數類型。這自動意味着_draw的第三個模板參數應該是一個函數,它也通過值來引用它的參數。即如果SourceFormatDestFormatunsigned __int32,則函數指針應該有void (*)(unsigned __int32, unsigned __int32)類型。相反,您試圖提供一個函數,它通過引用來引用它的參數,即指針類型爲void (*)(unsigned __int32 &, unsigned __int32 &)。這些都是完全沒有實現和不相容的指針類型。下面的簡單代碼將無法編譯出於同樣的原因

void foo(int&); 
void (*pf)(int) = foo; 
// ERROR: a value of type "void (*)(int &)" cannot be used to initialize an entity of type "void (*)(int)" 

您是如何看待它的?從實際的函數參數中刪除引用(改爲使用返回類型),或者將它們添加到模板參數聲明中。

另一個問題是,您正嘗試使用指向static函數(內部鏈接)的指針來對模板進行參數化。這在C++中是非法的。這說明該問題的簡單的例子可能如下

template <void (*P)()> void foo() {} 
static void bar() {} 
... 
foo<bar>(); 
// ERROR: template argument may not reference a non-external entity 

如果你想參數化模板的指針值,參數您提供必須指向實體外部聯動。您的編譯器可能允許您按原樣執行,但仍然是非法的。

最後,在C++中用分號結束獨立函數定義是非法的。這實際上被視爲「空聲明」,並且C++中沒有「空聲明」。許多編譯器允許這樣做,但它仍然是非法的。

P.S.另外,正如其他人已經注意到的那樣,您設法顛倒了非模板轉換器功能convertARGB_GREY中參數類型的順序。

+1

此外,該消息表明他有他的char和int混合起來(到OP,*讀*消息)。 – UncleBens 2010-02-03 20:19:49

+0

來UncleBens:你說得對,我應該仔細閱讀錯誤信息。我實際上停止閱讀它: 「無法從'void(__cdecl *)...轉換爲'void(__cdecl * const)」。愚蠢的是,我認爲這是'常量',無法轉換!我值得痛苦的死亡: - | – 2010-02-04 10:23:23

+0

To AndreyT:您定義爲非法的兩個問題 - 函數定義結束時的分號和作爲模板參數的非外部靜態函數 - 在Visual 2008中編譯得很好。我認爲損害可移植性,但另一方面它們聽起來很像舊的不必要的語言障礙比干淨的編碼標準...: - ? – 2010-02-04 10:36:36

相關問題