我有这个模板:
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
我认为很明显我不完全理解函数 - 参数......: - (
非常感谢提前
答案 0 :(得分:5)
您的代码中存在多个问题。
在您的代码中,当您致电_draw
时,SourceFormat
模板的DestFormat
和_draw
参数会提供显式参数。这些参数是普通的非引用整数类型。这自动意味着_draw
的第三个模板参数应该是一个按值获取其参数的函数。即如果SourceFormat
和DestFormat
为unsigned __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 :(得分:2)
我不知道你是否故意这样做,但你的模板参数是Source / Destintaion然后是Destination / Source。
请注意,当您执行_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(...)
尽管如此。)