gpt4 book ai didi

c++ - 通用函数调度机制

转载 作者:太空狗 更新时间:2023-10-29 20:23:42 26 4
gpt4 key购买 nike

我正在尝试编写一个通用的函数分派(dispatch)机制,在调用实际函数之前我会做一些额外的工作(例如,为函数的执行计时)。以下代码有效,但 void f(....) 类型的函数除外,因为我们正在声明 ret。

#define execute(fn, ...)    exec_helper(#fn, fn, ##__VA_ARGS__)
#define execute0(fn) exec_helper(#fn, fn)

template <typename TASK, typename... ARGS>
auto exec_helper(const char *fn_name, TASK&& task, ARGS&&... args)
{
//std::function<std::result_of_t<TASK(ARGS...)> ()> func
// = std::bind(std::forward<TASK>(task),
// std::forward<ARGS>(args)...);

#ifdef TIME_FUNC
auto start = std::chrono::steady_clock::now();
#endif

auto ret = task(std::forward<ARGS>(args)...);

#ifdef TIME_FUNC
auto end = std::chrono::steady_clock::now();
auto diff = end - start;
auto time = std::chrono::duration<double, std::milli>(diff).count();
std::cout << "\n" << fn_name << "\t = "
<< std::setprecision(3) << time << " ms\n";
#endif

return ret;
}

有没有办法让它也适用于这些类型的功能?也许使用一些模板技巧?

最佳答案

C++ 的一个有趣特性是您可以这样写:

return f();

即使 f 的返回类型是 void。这样,您实际上可以避免使用 ret 变量。

牢记这一点,以及析构函数的工作原理,您可以将 work-before-task 和 work-after-task 包装在一个类中——并分别在构造函数和析构函数中调用它们,如下所示:

struct watch
{
extern watch(char const *fn_name)
: _fn_name(fn_name),
_start(std::chrono::steady_clock::now()) {}

~watch()
{
auto end = std::chrono::steady_clock::now();
auto diff = end - _start;
auto time = std::chrono::duration<double, std::milli>(diff).count();
std::cout << "\n" << _fn_name << "\t = "
<< std::setprecision(3) << time << " ms\n";
}

char const *_fn_name;
decltype(std::chrono::steady_clock::now()) _start;
};

并将其用作:

template <typename TASK, typename... ARGS>
auto exec_helper(const char *fn_name, TASK&& task, ARGS&&... args)
{
#ifdef TIME_FUNC
watch start_watching { fn_name };
#endif

return task(std::forward<ARGS>(args)...);
}

希望对您有所帮助。


您甚至可以将包装类概括为:

struct invariant_executor //choose a more general name now!
{
using F = std::function<void()>;

invariant_executor(F before, F after): _after(std::move(after))
{
before();
}

~invariant_executor()
{
_after();
}
F _after;
};

并将其用作:

template <typename TASK, typename... ARGS>
auto exec_helper(const char *fn_name, TASK&& task, ARGS&&... args)
{
#ifdef TIME_FUNC
decltype(std::chrono::steady_clock::now()) start;
invariant_executor local
{
[&] { start = std::chrono::steady_clock::now(); },

[&] {
auto end = std::chrono::steady_clock::now();
auto diff = end - start;
auto time = std::chrono::duration<double, std::milli>(diff).count();
std::cout << "\n" << fn_name << "\t = "
<< std::setprecision(3) << time << " ms\n";
}
};
#endif

return task(std::forward<ARGS>(args)...);
}

现在您可以灵活地执行 invariant_executor 的构造函数和析构函数中的任何代码。

关于c++ - 通用函数调度机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31792139/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com