I'd like to wrap the result of a std::bind() or a lambda in a helper function that tracks the execution time of calls to the function. I'd like a generalized solution that will work with any number of parameters (and class methods) and is c++11 compatible.
My intent is to take the wrapped function and pass it to a boost::signals2::signal so the resulting function object needs to be identical in signature to the original function.
I'm basically looking for some magical class or function Wrapper that works like this:
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);
that would time how long it took to print 42.
Thanks!
If it's about performance, I strongly suggest not to doubly wrap functions.
You can do without those:
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)...);
};
}
See live demo:
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();
}
Prints (e.g.):
-- (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
UPDATE: c++11 version
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();
}
I believe what you want to do can be solved with variadic templates.
http://www.cplusplus.com/articles/EhvU7k9E/
You can basically "forward" the argument list from your outer std::function to the inner.
EDIT:
Below, I added a minimal working example using the variadic template concept. In main(...), a lambda function is wrapped into another std::function object, using the specified parameters for the inner lambda function. This is done by passing the function to measure as a parameter to the templated function measureTimeWrapper. It returns a function with the same signature as the function passed in (given that you properly define that lambda's parameter list in the template argument of measureTimeWrapper).
The function who's running time is measured just sits here and waits for a number of milliseconds defined by its parameter. Other than that, it is not at all concerned with time measuring. That is done by the wrapper function.
Note that the return value of the inner function is lost this way; you might want to change the way values are returned (maybe as a struct, containing the measured time and the real return value) if you want to keep it.
Remember to compile your code with -std=c++11 at least.
#include <iostream>
#include <cstdlib>
#include <functional>
#include <chrono>
#include <thread>
template<typename T, typename... Args>
std::function<double(Args...)> measureTimeWrapper(std::function<T> fncFunctionToMeasure) {
return [fncFunctionToMeasure](Args... args) -> double {
auto tsStart = std::chrono::steady_clock::now();
fncFunctionToMeasure(args...);
auto tsEnd = std::chrono::steady_clock::now();
std::chrono::duration<double> durTimeTaken = tsEnd - tsStart;
return durTimeTaken.count();
};
}
int main(int argc, char** argv) {
std::function<double(int)> fncMeasured = measureTimeWrapper<void(int), int>([](int nParameter) {
std::cout << "Process function running" << std::endl;
std::chrono::milliseconds tsTime(nParameter); // Milliseconds
std::this_thread::sleep_for(tsTime);
});
std::cout << "Time taken: " << fncMeasured(500) << " sec" << std::endl;
return EXIT_SUCCESS;
}
#include <iostream>
#include <functional>
template<typename Signature>
std::function<Signature> Wrapper(std::function<Signature> func)
{
return [func](auto... args)
{
std::cout << "function tracked" << std::endl;
return func(args...);
};
}
int lol(const std::string& str)
{
std::cout << str << std::endl;
return 42;
}
int main(void)
{
auto wrapped = Wrapper<int(const std::string&)>(lol);
std::cout << wrapped("Hello") << std::endl;
}
Replace the "function tracked"part with whatever tracking logic you want (timing, cache, etc.)
This requires c++14 though
Related
I'm trying to write a function that measures the time of execution of other functions.
It should have the same return type as the measured function.
The problem is that i'm getting a compiler error Variable has incomplete type 'void' when the return type is void.
Is there a workaround to solve this problem?
Help would be greatly appreciated, thanks!
#include <iostream>
#include <chrono>
template<class Func, typename... Parameters>
auto getTime(Func const &func, Parameters &&... args) {
auto begin = std::chrono::system_clock::now();
auto ret = func(std::forward<Parameters>(args)...);
auto end = std::chrono::system_clock::now();
std::cout << "The execution took " << std::chrono::duration<float>(end - begin).count() << " seconds.";
return ret;
}
int a() { return 0; }
void b() {}
int main()
{
getTime(a);
getTime(b);
return 0;
}
It's possible to solve this problem using specialization and an elaborate song-and-dance routine. But there's also a much simpler approach that takes advantage of return <void expression>; being allowed.
The trick is to fit it into this framework, by taking advantage of construction/destruction semantics.
#include <iostream>
#include <chrono>
struct measure_time {
std::chrono::time_point<std::chrono::system_clock> begin=
std::chrono::system_clock::now();
~measure_time()
{
auto end = std::chrono::system_clock::now();
std::cout << "The execution took "
<< std::chrono::duration<float>(end - begin).count()
<< " seconds.\n";
}
};
template<class Func, typename... Parameters>
auto getTime(Func const &func, Parameters &&... args) {
measure_time measure_it;
return func(std::forward<Parameters>(args)...);
}
int a() { return 0; }
void b() {}
int main()
{
getTime(a);
getTime(b);
return 0;
}
I'm working on a mechanism for creating "safe" callbacks, that won't cause undefined behavior when called after their parent object has been destroyed. The class should be generic enough to be able to wrap any callback, with void(...) callbacks simply being executed or not, depending on the status of the object that they are bound to, and callbacks that return a value returning a boost::optional with the returned value, if executed, or boost::none if not executed.The implementation is almost complete, but there are 2 things that make me worried that I don't fully understand my code...
If line 19 is uncommented and 18 commented out, the template won't compile - is this merely a syntactic problem that can be solved, or am I trying to use the result_of mechanism incorrectly (does the std::forward there change the semantics or is it superfluous?)
If line 88 is uncommented and 89 commented out, the compilation results in failure due to ambiguousness of the function call to fun, which I don't quite understand - it seems to me that fun(int&&) is an exact match, so why does the compiler complain of ambiguousness with fun(int) version?
If there are other subtle (or gross) errors, please comment as well.
Thanks.
#include <iostream>
#include <string>
#include <type_traits>
#include <utility>
#include <memory>
#include <boost/optional.hpp>
template<class Func>
class SafeCallback
{
public:
SafeCallback(std::shared_ptr<bool> guard, const Func& callback)
: guard_(guard)
, callback_(callback)
{}
template<class... Args>
// auto operator()(Args&&... args) -> typename std::enable_if<std::is_void<typename std::result_of<Func(std::forward<Args>(args)...)>::type>::value, // won't compile with: 19:91: error: invalid use of template-name 'std::result_of' without an argument list
auto operator()(Args&&... args) -> typename std::enable_if<std::is_void<typename std::result_of<Func(Args...)>::type>::value,
void>::type
{
std::cout << "trying void callback" << std::endl;
if(guard_.lock())
{
std::cout << "callback is still alive :)" << std::endl;
callback_(std::forward<Args>(args)...);
return;
}
std::cout << "uh-oh, callback is dead!" << std::endl;
}
template<class... Args>
auto operator()(Args&&... args) -> typename std::enable_if<!std::is_void<typename std::result_of<Func(Args...)>::type>::value,
boost::optional<typename std::result_of<Func(Args...)>::type>>::type
{
std::cout << "trying non-void callback" << std::endl;
if(guard_.lock())
{
std::cout << "callback is still alive :)" << std::endl;
return callback_(std::forward<Args>(args)...);
}
std::cout << "uh-oh, callback is dead!" << std::endl;
return boost::none;
}
bool isAlive()
{
return guard_.lock();
}
private:
std::weak_ptr<bool> guard_;
Func callback_;
};
class SafeCallbackProvider
{
public:
SafeCallbackProvider()
: guard_(new bool(true))
{}
virtual ~SafeCallbackProvider() = default;
template<class Func>
SafeCallback<Func> makeSafeCallback(const Func& callback)
{
return SafeCallback<Func>(guard_, callback);
}
private:
std::shared_ptr<bool> guard_;
};
struct A : SafeCallbackProvider
{
void fun()
{
std::cout << "---this is fun---" << std::endl;
}
int fun(int&& i)
{
std::cout << "&& this is && " << i << " && fun &&" << std::endl;
return i;
}
// int fun(int i) // fails to compile with: 123:48: error: call of overloaded 'fun(int)' is ambiguous
int fun(int& i)
{
std::cout << "---this is ---" << i << "--- fun---" << std::endl;
return i;
}
};
int main()
{
A* a= new A;
auto cb = a->makeSafeCallback(
[&]()
{
a->fun();
});
cb();
delete a;
cb();
std::cout << "\n----------\n\n";
A* a2= new A;
auto cb2 = a2->makeSafeCallback(
[&](int i)
{
return a2->fun(i);
});
cb2(5);
delete a2;
cb2(5);
std::cout << "\n----------\n\n";
A* a3= new A;
auto cb3 = a3->makeSafeCallback(
[&](int&& i)
{
return a3->fun(std::forward<int>(i));
});
cb3(5);
delete a3;
cb3(5);
return 0;
}
Note: this only answers the first question, because I apparently have the attention span of a fly. More coming soon.
std::result_of essentially performs some magic based on a function type that looks like a function call. In the line that works:
typename std::result_of<Func(Args...)>::type
This is the intended use, simulating the call of an instance of Func with values of types Args.... On the other hand:
typename std::result_of<Func(std::forward<Args>(args)...)>::type
This expands Args and args into a group of values, which then form a chain of ,-operators inside a functoin-style cast to Func. The whole thing is an expression instead of the type std::result_of expects.
It looks like you're halfway to using decltype instead, which would look like:
decltype(std::declval<Func&>()(std::forward<Args>(args)...))
... or, if you can be bothered to move it underneath callback_'s declaration:
decltype(callback_(std::forward<Args>(args)...))
Rules of Overloading are that .
Signature of function should be different.
In both the case compiler is finding same signature, try to change the signature and see the result.
In the C++ coroutines TS (2017), there is an example of an awaitable object.
template <class Rep, class Period>
auto operator co_await(std::chrono::duration<Rep, Period> d) {
struct awaiter {
std::chrono::system_clock::duration duration;
...
awaiter(std::chrono::system_clock::duration d) : duration(d){}
bool await_ready() const { return duration.count() <= 0; }
void await_resume() {}
void await_suspend(std::experimental::coroutine_handle<> h){...}
};
return awaiter{d};
}
using namespace std::chrono;
my_future<int> h();
my_future<void> g() {
std::cout << "just about go to sleep...\n";
co_await 10ms;
std::cout << "resumed\n";
co_await h();
}
Like a typical StackOverflow Question, it will not compile. After cursing quietly for a while, I decided to turn it into a [MCVE] -- for learning. The code below compiles and runs on VC++17 with /await enabled. I think it probably does approximately what the TS authors intended. Alas, it employs a detached thread. It is not easy to see how that thread could be harvested via join or future::get or signal_all_at_thread_exit() or ...
For example, join cannot be added to a destructor for awaiter. In the spawned thread, h.resume() causes the awaiter object to be moved into the spawned thread and its (default) constructor called there. So the destructor is called in a different thread than the constructor.
The question, aside from "Is this what the TS intended?", is "Can this be improved, in a reasonably economical way, to tend to the dangling thread?" (And if so how?)
#include <experimental/coroutine>
#include <future>
#include <thread>
namespace xtd = std::experimental;
template <class Rep, class Period>
auto operator co_await(std::chrono::duration<Rep, Period> dur) {
struct awaiter {
using clock = std::chrono::high_resolution_clock;
clock::time_point resume_time;
awaiter(clock::duration dur) : resume_time(clock::now()+dur) {}
bool await_ready() { return resume_time <= clock::now(); }
void await_suspend(xtd::coroutine_handle<> h) {
std::thread([=]() {
std::this_thread::sleep_until(resume_time);
h.resume(); // destructs the obj, which has been std::move()'d
}).detach(); // Detach scares me.
}
void await_resume() {}
};
return awaiter{ dur };
}
using namespace std::chrono;
std::future<int> g() {
co_await 4000ms;
co_return 86;
}
template<typename R>
bool is_ready(std::future<R> const& f)
{ return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }
int main() {
using std::cout;
auto gg = g();
cout << "Doing stuff in main, while coroutine is suspended...\n";
std::this_thread::sleep_for(1000ms);
if (!is_ready(gg)) {
cout << "La lala, lala, lala...\n";
std::this_thread::sleep_for(1500ms);
}
cout << "Whew! Done. Getting co_return now...\n";
auto ret = gg.get();
cout << "coroutine resumed and co_returned " << ret << '\n';
system("pause");
return ret;
}
Can this be improved, in a reasonably economical way, to tend to the dangling thread?
You can use "thread pool" implementation, instead of on-demand detached thread.
Here is toy example:
https://gist.github.com/yohhoy/a5ec6d4aeeb4c60d3e4f3adfd1df9ebf
I have a function foo that returns a future. foo will register a callback which will be called after foo returns.
future<int> foo() {
promise<int> p;
future<int> ret(p.get_future());
thread(bind([] (promise<int> &&p) {
this_thread::sleep_for(chrono::seconds(3));
p.set_value(10);
}, move(p))).detach();
return move(ret);
}
int main()
{
auto f = foo();
cout << f.get() << endl;
return 0;
}
But it seems like that std::bind forwards the rvalue reference as a lvalue reference so that can not be successfully compiled. Is there any way to fix it?
I have to write an ugly class to move the promise object:
template<typename T>
class promise_forward {
promise<T> promise_;
public:
promise_forward(promise<T> &&p) :
promise_(move(p)) {}
promise_forward(promise_forward<T> &&other) :
promise_(move(other.promise_)) {}
operator promise<T> () {
return move(promise_);
}
};
future<int> foo() {
promise<int> p;
future<int> ret(p.get_future());
thread(bind([] (promise<int> &&p) {
this_thread::sleep_for(chrono::seconds(3));
p.set_value(10);
}, promise_forward<int>(move(p)))).detach();
return ret;
}
int main()
{
auto f = foo();
cout << f.get() << endl;
return 0;
}
You, basically, doesn't need std::bind here (well , I believe so =)).
Here is a quick draft of a simplest async task launcher. It almost same as yours, but, just a little more generic: it can accept any function objects and it is less intrusive: function objects doesn't know nothing about promises or threading at all.
There are may be mistakes (I'm quite sure they are). And, of course, it is far far away, from std::async implementation (which, generally, more than just thread launcher, but, ideally, have a huge thread management back-end).
#include <thread>
#include <future>
#include <iostream>
#include <chrono>
template< class Function, class... Args>
std::future<typename std::result_of<Function(Args...)>::type> my_async(Function && f, Args && ... args)
{
typedef typename std::result_of<Function(Args...)>::type ret_type;
std::promise<ret_type> p;
auto fut = p.get_future();
// lambda in separate variable, just to improve readability
auto l = [](Function && f, Args && ... args, std::promise<ret_type> && p)
{
p.set_value(f(args...));
};
std::thread th(l, std::move(f), std::move(args...), std::move(p));
th.detach();
return std::move(fut);
}
int wannaRunAsync(int i)
{
return i;
};
int main()
{
auto fut = my_async(&wannaRunAsync, 42);
auto fut2 = my_async([](int i) -> int { return i; }, 42);
std::cout << fut.get() << std::endl;
std::cout << fut2.get() << std::endl;
std::cin.get();
return 0;
}
I was able to compile and run it with
g++-4.8 and
clang++ but with msvc 2012 and 2013 preview it doesn't even compiles (probably, due to errors).
I've not tested this code at all, so be careful =) Hope it helps.
So I have the following code:
#include <iostream>
template <typename T>
class funcky
{
public:
funcky(char const* funcName, T func)
: name(funcName), myFunc(func)
{
}
//private:
char const* name;
T myFunc;
};
#if 0
int main(void)
{
char const* out = "nothing";
// requires template args
funcky test("hello", [&](int x, int y) -> int
{
out = "YES";
return x + y;
});
std::cout << test.name << " = " << test.myFunc(1, 2) << std::endl;
std::cout << test.name << " = " << out << std::endl;
return 0;
}
int main2(void)
{
funcky<void(*)(void)> test("hello", [&, this](void) -> void
{
std::cout << this->name << std::endl;
});
test.myFunc();
return 0;
}
#endif
int main(void)
{
char const* out = "nothing";
auto myFunc = [&](int x, int y) -> int
{
out = "YES";
return x + y;
};
funcky<decltype(myFunc)> test("hello", myFunc);
std::cout << test.name << " = " << test.myFunc(1, 2) << std::endl;
std::cout << test.name << " = " << out << std::endl;
return 0;
}
The top chunk is a function holder that holds a lambda and a name for it.
Next is what I'd like to use API-wise, but fails due to no template arguments being specified.
After that, there's my wondering if it's possible to have a 'this' of a specific type (such as funcky) be used in a lambda not declared inside it. Wishful thinking.
At the very end is code that compiles but uses a lambda outside the funcky constructor and decltype.
Are such things possible in C++11? How I accomplish said things?
Also unless it can kind of have the same API, try not to guess what I'm doing as if I can't do it this way, I'll just rewrite it in a simpler way. It's not worth the effort.
If you want to provide a way for a user to supply a callback to your class, you're better off using std::function, since templating the class on the function / functor type is not a very useful thing to do, as you experienced.
The problem arises from the fact that you can't just take anything in. You should have clear requirements on what can be passed as a callback, since you should know how you want to call it later on. See this on why I make the constructor a template.
#include <functional>
#include <utility>
struct X{
template<class F>
X(F&& f) : _callback(std::forward<F>(f)) {} // take anything and stuff it in the 'std::function'
private:
std::function<int(int,int)> _callback;
};
int main(){
X x([](int a, int b){ return a + b; });
}
If, however, you don't know how the callback is going to be called (say, the user passes the arguments later on), but you want to support that, template your type on the signature of the callback:
#include <iostream>
#include <functional>
#include <utility>
template<class Signature>
struct X{
template<class F>
X(F&& f) : _callback(std::forward<F>(f)) {} // take anything and stuff it in the 'std::function'
private:
std::function<Signature> _callback;
};
int main(){
X<int(int,int)> x1([](int a, int b){ return a + b; });
X<void()> x2([]{ std::cout << "wuzzah\n";});
}
Something like
template<typename Functor>
funcky<typename std::decay<Functor>::type>
make_funcky(const char* name, Functor&& functor)
{ return { name, std::forward<Functor>(functor) }; }
can be helpful for things like:
auto test = make_funcky("hello", [&](int x, int y) -> int
{
out = "YES";
return x + y;
});
However, inside a lambda expression this always refers to the immediate this outside of the expression. It's not a delayed reference to some this present at the time of the invocation -- it's not an implicit parameter. As such it doesn't make sense to want 'another type' for it.