函数类型不是模板非类型参数的有效类型?

时间:2013-12-24 09:16:06

标签: c++ templates opengl raii partial-specialization

OpenGL定义了C函数来管理资源。我写了一个简单的包装器以RAII的方式处理它们。函数对类似于unsigned glCreateProgram()void glDeleteProgram(unsigned program)。但是,有一些函数对可用于void glGenBuffers(size_t n, unsigned* buffers)void glDeleteBuffers(size_t n, const unsigned* buffers);等资源数组。对于前者,我写了一个简单的类来完成这项工作,而后者我写了另一个处理数组的类。但是,我注意到有时我只使用一个缓冲区或纹理,我不需要花费一个向量,我认为如果release函数在开始时采用一个size参数,我会专门使用类析构函数但是...

template <typename T_res,
          typename T_release_func,
          T_release_func func>
struct GL_resource
{
    GL_resource(T_res name_) : name{name_}
    {
    }

    ~GL_resource()
    {
        func(name);
    }

private:
    T_res name;
};

template <typename T_res, typename FT, FT func, typename RT, typename DT>
struct GL_resource<T_res, RT (size_t, DT*), func>
{
    ~GL_resource()
    {
        func(1, name);
    }
};   

对于上述SSCCE g ++咆哮:

  

错误:'RT(unsigned int,DT *)'不是模板非类型参数struct GL_resource的有效类型

然后我写了一个虚函数void release(size_t, int*) {}并将其改写为

template <typename T_res, typename FT, FT func>
struct GL_resource<T_res, decltype(release), release>
{
    ~GL_resource()
    {
        func(1, name);
    }
};

这次我得到了:

  

错误:'void(unsigned int,int *)'不是模板非类型参数struct GL_resource的有效类型。

有人可以解释原因吗?

1 个答案:

答案 0 :(得分:2)

函数不是值,因此它们不能是非类型模板参数;但指向函数的指针可以是:

template <typename T_res, typename RT, typename DT, RT (*func) (size_t, DT*)>
struct GL_resource<T_res, RT (*)(size_t, DT*), func>
{
    ~GL_resource()
    {
        func(1, name);
    }
};   

请注意,即使用作非类型模板参数,函数也会受到指针衰减的影响,因此FT将始终是指针到函数类型,而不是函数类型。