【问题标题】:C++ Get name of a template function argumentC++ 获取模板函数参数的名称
【发布时间】:2022-01-13 02:02:12
【问题描述】:

我想将所有 glXXXX 调用替换为 GL_CALL(N, ...),以便我可以打印函数和参数来跟踪调用。

例如,将glClearColor(0.0f, 0.0f, 0.0f, 1.0f) 替换为GL_CALL(ClearColor, 0.0f, 0.0f, 0.0f, 1.0f),在控制台中我得到[GL_CALL] glClearColor(0, 0, 0, 1)

#include <iostream>

template <class T>
void GL_TRACE_PRINT(T const &t) {
  std::cout << t << ",";
}

template<typename T, typename... Args>
void GL_TRACE_PRINT(T n, Args ... args) {
  GL_TRACE_PRINT(n);
  GL_TRACE_PRINT(args...);
}

#define GL_STR(s) #s

template <class F, typename ...Args>
auto GL_INVOKE(F f, Args && ...args) {
  std::cout << "[GL_CALL] " << GL_STR(f) << '(';
  GL_TRACE_PRINT(std::forward<Args>(args)...);
  std::cout << ")\n";
  return f(std::forward<Args>(args)...);
}

#define GL_CALL(N, ...)                                       \
  GL_INVOKE(gl##N, __VA_ARGS__);

但是如何打印GL_INVOKE中的函数名呢?谢谢。 或者有更好的方法吗?

目前的输出是,glXXX 函数名都是f

[GL_CALL] f(0,0,0,1,)
[GL_CALL] f(0,0,0,1,)

【问题讨论】:

  • __function__ 宏?
  • 如果你想跟踪调用,建议你使用一些宏,如__line____function等。或者,你可以使用boost.stacktrace。或者,如果您使用 C++23,您可以使用 &lt;stacktrace&gt; 中的内容。
  • __FUNCTION__ 宏输出 "[GL_CALL] GL_INVOKE(0,0,0,1,)" @JohnFilleau
  • 添加两个参数 GL_TRACE_PRINT 将有助于删除最后一个 "," :)

标签: c++ templates


【解决方案1】:

您可以将函数的字符串名称传递给GL_INVOKE,如下所示:

template <class F, typename ...Args>
auto GL_INVOKE(const char* fname, F f, Args && ...args) {
  std::cout << "[GL_CALL] " << fname << '(';
  GL_TRACE_PRINT(std::forward<Args>(args)...);
  std::cout << ")\n";
  return f(std::forward<Args>(args)...);
}

#define GL_INVOKE_F(N, ...) \
  GL_INVOKE(#N, N, ## __VA_ARGS__) 

#define GL_CALL(N, ...)  \
  GL_INVOKE_F(gl##N , ## __VA_ARGS__)

Demo.

另外,你的GL_TRACE_PRINT可以用C++17折叠表达式实现,会简洁很多。

template <class... Args>
void GL_TRACE_PRINT(Args const&... args) {
  ((std::cout << args << ","), ...);
}

【讨论】:

  • 哈哈,谢谢。这很聪明。
  • 顺便说一句。对于没有任何参数的 glCreateProgram。 GL_CALL 编译失败。错误:预期表达式 GLuint program = GL_CALL(CreateProgram);注意:从宏 'GL_CALL' 扩展 GL_INVOKE(GL_STR(gl##N), gl##N, VA_ARGS)
  • 我怎样才能修复模板,以便它可以接受 glFunction 而没有任何参数?谢谢。
  • @wqyfavor。您可以使用## 删除逗号,请参阅更新。
  • @wqyfavor 如果您将模板用于所有功能,在最坏的情况下,bin 文件的大小会爆炸。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多