c++ - 如何在编译时检查函数是否在全局范围内声明

标签 c++ templates opengl

让我有一个标题,例如#include <GL/gl.h> .它包含 OpenGL API 函数的子集。我需要这样的东西:

static_assert(has_glDrawArraysIndirect::value, "There is no glDrawArraysIndirect");

或者更好:

PFNGLDRAWARRAYSINSTANCEDPROC ptr_glDrawArraysIndirect = ptr_to_glDrawArraysIndirect::ptr;

在哪里ptr_to_glDrawArraysIndirect::ptr展开指向 glDrawArraysIndirect 的指针(如果已定义)或 stub 函数 stub_glDrawArraysIndirect否则。

我的目标操作系统非常具体。任何基于链接器的解决方案(如 GetProcAddressdlsym )对我都不起作用,因为没有动态链接器。不止,我的驱动不提供glXGetProcAdrress也不wglGetProcAddress ,基本上没有办法在运行时通过函数名查询指针(其实我想实现这样的机制)。

有什么想法吗?

最佳答案

这是一个可以在编译时检测到它并产生一个 bool 值的答案。它的工作原理是在命名空间中创建一个同名的模板函数,然后在 is_defined() 函数中使用该命名空间。如果真正的 glDrawArraysIndirect() 存在,它将优先于模板版本。如果您注释掉 glDrawArraysIndirect() 的第一个声明,底部的静态断言将触发。

Test on GodBolt

#include <type_traits>

enum GLenum {};

void glDrawArraysIndirect(GLenum, const void*);

namespace detail {
    struct dummy;

    template<typename T>
    dummy& glDrawArraysIndirect(T, const void*);
}

constexpr bool is_defined()
{
    using namespace detail;
    using ftype = decltype(glDrawArraysIndirect(GLenum(), nullptr));
    return std::is_same<ftype, void>();
}

static_assert(is_defined(), "not defined");

稍微调整一下,您就可以将自定义函数设为模板并使用类似的技巧

ideone.com

#include <type_traits>
#include <iostream>

//#define USE_REAL

enum GLenum {TEST};

typedef void (*func_type)(GLenum, const void*);

#ifdef USE_REAL
void glDrawArraysIndirect(GLenum, const void*);
#endif

namespace detail {
    struct dummy {};

    template<typename T = dummy>
    void glDrawArraysIndirect(GLenum, const void*, T = T())
    {
        std::cout << "In placeholder function" << std::endl;
    }

}

void wrapDraw(GLenum x, const void* y)
{
  using namespace detail;
  glDrawArraysIndirect(x, y);
}

#ifdef USE_REAL
void glDrawArraysIndirect(GLenum, const void*)
{
    std::cout << "In real function" << std::endl;
}
#endif

int main()
{
    wrapDraw(TEST, nullptr);
}

关于c++ - 如何在编译时检查函数是否在全局范围内声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35944030/

相关文章:

c++ - RapidXML 加载 xml 文件

c++ - 模板函数重载歧义

c++ - Perlin Noise 在 Y 轴上得到错误的值 (C++)

c - 我的 open gl 无法正常工作?

OpenGL 和远程桌面

c++ - 迭代 vector 和调用函数

c++ - OpenGL 执行非常缓慢

c++ - 静态 CRTP 类不知道派生类型?

c++ - 公共(public)继承类无法访问基类的重载非虚拟公共(public)方法?

c++ - 从同一类的两个不同模板拷贝继承时重载