C++:忽略候选模板:模板参数的显式指定参数无效

标签 c++ templates template-function

我有这个函数头:

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) { /* .. */ }

我得到这个错误:

注意:候选模板被忽略:模板参数“getFunc”的显式指定参数无效 [3]

为什么?

最佳答案

我怀疑所有这些函数都是自由函数。当您声明一个自由函数 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 模式下在 Clang 3.1 和 GCc 4.4.5 上编译良好,没有警告。如果我将 static 留在其中,我会得到一个类似的错误 + 注意你用 Clang 得到的东西,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 模式下不遵守这一点,它仍然只允许具有外部链接的函数。

关于C++:忽略候选模板:模板参数的显式指定参数无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8629839/

相关文章:

c++ - 在 x3 中动态切换符号表

C++构造函数中父类(super class)的init成员

c++ - 如何在不触及函数本身的情况下暂停和恢复 C++11 std::thread 的函数?

c++ - 将值映射到类型以避免 C++ 中的 switch 语句

c++ - 为什么不将自动向下转换应用于模板函数?

c++ - 如何使用 Win32 API 获取任何线程的堆栈大小和堆栈限制

c++ - 使用可变参数模板解包参数列表时获取参数索引

c++ - 模板函数名作为模板参数?

c++ - 为什么ADL找不到函数模板?

c++ - C++ 模板函数是线程安全的吗?