我想跟踪我的所有OpenGL调用。为此,我有以下宏:
#define EXEC_OPENGL(NAME, ARGUMENTS) debugOpengl(TOSTRING(NAME), [](void) { return NAME ARGUMENTS; })
EXEC_OPENGL(glDoSomething, (1, 2, 3, 4));
debugOpengl
功能代码与此类似:
void debugOpengl(char const * name, std::function<void ()> const & exec)
{
GLenum err;
exec();
while((err = glGetError()) != GL_NO_ERROR) {
std::cerr << "OpenGL Error: " << name << " " << err << std::endl;
}
}
template <typename Ret>
Ret debugOpengl(char const * name, std::function<Ret ()> const & exec)
{
GLenum err;
auto ret = exec();
while((err = glGetError()) != GL_NO_ERROR)
std::cerr << "OpenGL Error: " << name << " " << err << std::endl;
return ret;
}
这段代码不起作用,因为(至少在GCC 7上)当涉及返回void的函数时,宏中定义的lambda无效(因为void value not ignored as it ought to be
)。
我也尝试过写一个模板仿函数类,但它最终是一个痛苦而且没有用(我的完美转发无法正确转发文字数字)。
什么是在调用函数之前和之后简单执行某些东西的好方法,假设我可以用宏包装所有调用它?
答案 0 :(得分:1)
您可以使用RAII显示错误:
template <typename F>
class Finally {
public:
Finally(F f) : f{f} {}
Finally(const Finally&) = delete;
Finally& operator=(const Finally&) = delete;
~Finally() noexcept {
try {
f();
} catch (...) {
std::cerr << "Exception during stack unwinding" << std::endl;
}
}
private:
F f;
};
template <typename F>
decltype(auto) debugOpengl(const char* name, F&& f)
{
Finally finally{[name](){
GLenum err;
while((err = glGetError()) != GL_NO_ERROR) {
{
std::cerr << "OpenGL Error: " << name << " " << err << std::endl;
}
}};
return f();
}
提供的代码使用C ++ 17,但可以在C ++ 11中完成
答案 1 :(得分:0)
这是一个GCC错误,since fixed:如果lambda’s return type返回该类型的表达式,则deduced as void
为qlot
。