jfo*_*erg 2 c++ metaprogramming
我想编写一个调试宏,在出现错误时打印调用的函数的名称。问题是有些函数返回值,我想从宏返回任何值。
\n这是我的尝试:
\n#define check(expr) _check_expr(#expr, expr)\n\nextern bool check_for_error();\n\ntemplate <typename T> inline T _check_expr(const char *str, T value)\n{\n if (check_for_error()) {\n fprintf(stderr, "Failure: %s\\n", str);\n }\n\n return value;\n}\nRun Code Online (Sandbox Code Playgroud)\n我遇到的问题是,有时T = void编译器不会让我将类型表达式传递void给函数:
../src/render.cc: In constructor \xe2\x80\x98render::impl::impl()\xe2\x80\x99:\n../src/render.cc:34:20: error: invalid use of void expression\n 34 | check(glDisable(GL_DEPTH_TEST));\nRun Code Online (Sandbox Code Playgroud)\n我无法重新定义在宏下调用的函数check或check_for_error函数,这些函数是我的程序外部的。此外,在计算表达式之后需要检查错误。
C++中有没有好的方法来解决这个问题?
\n类似于:“如果该表达式的 decltype 为 void,则生成此代码,否则生成该代码”。
\nvoid 函数可以返回 void 表达式。这也适用于 lambda:
#define check(expr) _check_expr(#expr, [&] () { return expr; })
extern bool check_for_error();
template <typename Fn>
inline auto _check_expr(const char *str, Fn fn)
{
auto check_ = [str]() {
if (check_for_error()) {
fprintf(stderr, "Failure: %s\n", str);
}
};
if constexpr (std::is_same_v<std::invoke_result_t<Fn>, void>) {
fn();
check_();
} else {
auto v = fn();
check_();
return v;
}
}
Run Code Online (Sandbox Code Playgroud)
可能有更好的解决方案,但这可行。此外,这至少需要当前形式的 C++17,但可能可以向后移植到 C++14 甚至 C++11。
https://wandbox.org/permlink/YHdoyKL0FIoJUiQb查看代码。