c++ - 将函数用作非类型模板参数时出错

标签 c++ function templates parameters

我有这个模板:

        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

我想很明显我没有完全理解函数作为参数...:-(

提前致谢

最佳答案

您的代码中有几个问题。

在您的代码中,当您调用 _draw 时,将提供 _draw 模板的 SourceFormatDestFormat 参数带有明确的参数。这些参数是普通的非引用整数类型。这自动意味着 _draw 的第三个模板参数应该是一个函数,它也按值获取其参数。 IE。如果 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++ 中没有“空声明”。许多编译器允许这样做,但它仍然是非法的。

附言此外,正如其他人已经指出的那样,您设法颠倒了非模板转换器函数 convertARGB_GREY 中参数类型的顺序。

关于c++ - 将函数用作非类型模板参数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2195056/

相关文章:

c++ - GCC 中的通用 lambda

python - Django ManyToMany 模板问题

postgresql - PostgreSQL 中的函数调用行为不当

PHP 函数作为参数默认值

.net - 何时在 .NET 中使用共享方法

c++ - 为什么成员模板方法必须在类外使用 template<> 进行专门化

c++ - 复制构造动态分配对象的问题

c++ - 如何自动更新状态栏消息?

c++ - 如何在 "header file (.h)"中的现有 "C++ Project"中创建新的 "Microsoft Visual Studio Community 2015"?

c++ - std::is_default_constructible<T> 错误,如果构造函数是私有(private)的