我希望对某个库中的函数的所有调用都包含对我的函数的调用。
例如,每当调用库
<glad/glad.h>
中的函数时,我的函数 log()
都会在运行库函数之前被调用。
我一直在阅读有关 c++20 概念的内容。这些可以在不使用宏的情况下完成任务吗?
我一直在研究这样的函数:
template<typename glFunction, typename ReturnType, typename... Params>
auto glCallImpl(const char* filename, const std::uint_fast32_t line, glFunction function, ReturnType& returnValue, Params... params)
->typename std::enable_if_t<!std::is_same_v<void, decltype(function(params...))>, bool>
{
returnValue = function(std::forward<Params>(params)...);
return check_gl_errors(function, filename, line);
}
不过他们似乎没有使用 C++ 的最新功能。我想尽可能使用概念。
如果这些是全局函数,你可以做得更好:
template<auto function>
struct call;
template<typename Return, typename... Args, Return(*function)(Args...)>
struct call<function> {
std::expected<Return, std::error_code> operator()(Args&&... args, std::source_location loc = std::source_location::current()) {
auto returnvalue = function(std::forward<Args>(args)...);
// Assuming check_gl_errors also returns std::expected<Return, std::error_code>
return check_gl_errors(returnvalue, loc.file_name(), loc.line());
}
};
// Usage:
call<::gl_do_stuff>(1, 2, 3);
(免责声明:我凭记忆想出这个只是为了展示这个想法,你可能需要在它可用之前修复一些错误。尽管我已经多次使用这个方案,所以这个原理是有效的。)
将其设为可调用结构而不是函数的原因是,这为我们提供了基于我们尝试包装的函数的参数推导。因此,如果函数采用 unsigned int 并且我们传递
-5
,则这是调用站点的编译器警告。如果我们根据传递的内容来推断参数,-5
将被推断为int
,这在最坏的情况下会导致未诊断的意外不当行为。