gpt4 book ai didi

c++ - 将 c++11 std::function 包装在另一个 std::function 中?

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

我想将 std::bind() 或 lambda 的结果包装在一个跟踪函数调用执行时间的辅助函数中。我想要一个通用的解决方案,它可以使用任意数量的参数(和类方法)并且与 c++11 兼容。

我的意图是获取包装函数并将其传递给 boost::signals2::signal,因此生成的函数对象需要在签名上与原始函数相同。

我基本上是在寻找一些像这样工作的神奇类或函数 Wrapper:

std::function<void(int)> f = [](int x) {
std::cerr << x << std::endl;
};

boost::signals2::signal<void(int)> x_signal;
x_signal.connect(Wrapper<void(int)>(f));
x_signal(42);

这就是打印 42 所花费的时间。

谢谢!

最佳答案

如果是关于性能,我强烈建议不要双重包装函数。

你可以没有那些:

template <typename Caption, typename F>
auto timed(Caption const& task, F&& f) {
return [f=std::forward<F>(f), task](auto&&... args) {
using namespace std::chrono;

struct measure {
high_resolution_clock::time_point start;
Caption const& task;
~measure() { std::cout << " -- (" << task << " completed in " << duration_cast<microseconds>(high_resolution_clock::now() - start).count() << "µs)\n"; }
} timing { high_resolution_clock::now(), task };

return f(std::forward<decltype(args)>(args)...);
};
}

查看现场演示:

Live On Coliru

#include <chrono>
#include <iostream>

template <typename Caption, typename F>
auto timed(Caption const& task, F&& f) {
return [f=std::forward<F>(f), task](auto&&... args) {
using namespace std::chrono;

struct measure {
high_resolution_clock::time_point start;
Caption const& task;
~measure() { std::cout << " -- (" << task << " completed in " << duration_cast<microseconds>(high_resolution_clock::now() - start).count() << "µs)\n"; }
} timing { high_resolution_clock::now(), task };

return f(std::forward<decltype(args)>(args)...);
};
}

#include <thread>

int main() {
using namespace std;
auto f = timed("IO", [] { cout << "hello world\n"; return 42; });
auto g = timed("Sleep", [](int i) { this_thread::sleep_for(chrono::seconds(i)); });

g(1);
f();
g(2);

std::function<int()> f_wrapped = f;
return f_wrapped();
}

打印(例如):

 -- (Sleep completed in 1000188µs)
hello world
-- (IO completed in 2µs)
-- (Sleep completed in 2000126µs)
hello world
-- (IO completed in 1µs)
exitcode: 42

更新:c++11 版本

Live On Coliru

#include <chrono>
#include <iostream>

namespace detail {

template <typename F>
struct timed_impl {
std::string _caption;
F _f;

timed_impl(std::string const& task, F f)
: _caption(task), _f(std::move(f)) { }

template <typename... Args>
auto operator()(Args&&... args) const -> decltype(_f(std::forward<Args>(args)...))
{
using namespace std::chrono;

struct measure {
high_resolution_clock::time_point start;
std::string const& task;
~measure() { std::cout << " -- (" << task << " completed in " << duration_cast<microseconds>(high_resolution_clock::now() - start).count() << "µs)\n"; }
} timing { high_resolution_clock::now(), _caption };

return _f(std::forward<decltype(args)>(args)...);
}
};
}

template <typename F>
detail::timed_impl<F> timed(std::string const& task, F&& f) {
return { task, std::forward<F>(f) };
}

#include <thread>

int main() {
using namespace std;
auto f = timed("IO", [] { cout << "hello world\n"; return 42; });
auto g = timed("Sleep", [](int i) { this_thread::sleep_for(chrono::seconds(i)); });

g(1);
f();
g(2);

std::function<int()> f_wrapped = f;
return f_wrapped();
}

关于c++ - 将 c++11 std::function 包装在另一个 std::function 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35007560/

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