这里有一个答案,它可以在编译时检测它并生成一个布尔值。它的工作原理是在命名空间中创建一个相同名称的模板函数,然后在
is_defined()
方法中使用该命名空间。如果真正的
glDrawArraysIndirect()
存在,则会优先于模板版本。如果您注释掉
glDrawArraysIndirect()
的第一个声明,则底部的静态断言将触发。
在 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>
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);
}