C++: How to pass a function+arguments as parameter without executing it? - c++

I have 3 algorithms function:
void algo1(int para1, int para2);
void algo2(int para1, int para2);
void algo3(int para1, int para2);
and I want set a timer to test these functions' efficiency
int get_execute_time( void(*f)(int para1, int para2) );
I pass the function as parameter to get_execute_time to avoid abundance, however, the problem is I also need to pass the arguments, which is para1, para2.
so I let timer function change to
get_execute_time( void(*f)(int para1, int para2) ,
int para1, int para2) {
(*f)(para1, para2); // call it
}
and, the code above seems ugly to me, so is there any option to wrap the code and let the code execute later in C++?
so that I can do like this:
// definition
get_execute_time(this_code_will_execute_later) {
this_code_will_execute_later();
};
// usage
get_execute_time(algo1(para1, para2));
Temporary solution: utilize class to implement closure-like thing( inspired from Do we have closures in C++?
class timer {
private:
int para1;
int para2;
public:
timer(int para1, int para2);
operator () (void(*f)(int para1, int para2)) { (*f)(para1, para2) }
}
// thus we can write these following code
timer timer(para1, para2);
std::cout << "run " << timer(algo1) << " ms";
std::cout << "run " << timer(algo2) << " ms"
std::cout << "run " << timer(algo3) << " ms"
So, Do exist better options? Thanks anyway!

You can do this with either std::bind or via a lambda. For example (just one parameter shown for brevity):
#include <iostream>
#include <functional>
void get_execute_time (std::function <void (void)> f)
{
f ();
}
void foo (int i)
{
std::cout << i << '\n';
}
int main()
{
int param = 42;
auto f1 = std::bind (foo, param);
get_execute_time (f1);
++param;
auto f2 = [param] { foo (param); };
get_execute_time (f2);
}
Output:
42
43
Live demo

Related

Call function object from doIt function

#include <iostream>
void hello1() {
std::cout << "Hello from normal\n";
}
auto hello2 = [] {
std::cout << "Hello from lamda\n";
};
class hello
{
public:
hello() {}
void operator()(std::string str) {
std::cout << "From functor " << str << std::endl<<std::endl;
}
};
void doIt(void(*f)()) {
f();
}
int main() {
hello1();
hello2();
hello hello3;
hello3("Hello");
doIt(hello1);
doIt(hello2);
doIt(hello3); //How can I do this?
}
I just started learning function objects and I cannot call function object from doIt function
How can I call the last function object with doIt function?
Any help would be appreciated.

How to prevent compilation of passed lambda, if arguments are not references

In one of my projects I'm using a small utility function, which takes a Message struct and a lambda function, that modifies this message struct.
Now, I unintentionally passed a lambda without the necessary reference &. It perfectly compiles, but doesn't gave the desired output.
As for me, there should be one of the two following behaviors:
Forgetting to write auto&, but just auto should lead to compilation errors
Writing just auto should be interpreted as auto&.
It is possible to prevent compilation in case of a missing & or even better to interpret auto as auto& automatically?
#include <iostream>
#include <functional>
#include <boost/variant.hpp>
struct Message {
int x;
int y;
};
void changeMessage(Message& m, const std::function<void(Message&)>& messageModifier) {
std::cout << "Message before:" << m.x << " " << m.y << "\n";
messageModifier(m);
std::cout << "Message after:" << m.x << " " << m.y << "\n";
}
int main(int, char**) {
{
std::function<void(int&)> f = [](int&) {};
std::function<void(int)> g = [](int) {};
f = g; // This compiles.
}
{
std::function<void(int&)> f = [](int&) {};
std::function<void(int)> g = [](int) {};
//g = f; // This does not compile. Makes perfect sense.
}
Message m{ 10,20 };
{
changeMessage(m, [](auto m) { m.x++; m.y--; }); // User unintentionally forgot &! Can I prevent this from compilation?
std::cout << "Message outside: " << m.x << " " << m.y << "\n";
}
{
changeMessage(m, [](auto& m) { m.x++; m.y--; });
std::cout << "Message outside: " << m.x << " " << m.y << "\n";
}
}
One way to prevent passing Message by value (and auto itself is never a reference) is to disable copy construction:
struct Message {
Message() = default;
Message(const Message&) = delete;
int x;
int y;
};
Another solution suggested by #L. F. is to check that lambda doesn't accept rvalues:
template<class Fn>
void change_message(Message& m, Fn fn) {
static_assert(!std::is_invocable_v<Fn, Message&&>);
fn(m);
}

Calling method that modifies a field while another method that uses that field is executing

I have a question regarding the outside modification of a running method.
Given this C++ class:
#include <iostream>
class Foo {
public:
Foo()
: runBar(true) {}
void bar() {
int i = 0;
while(this->runBar) {
std::cout << "Loop " << i++ << std::endl;
}
std::cout << "Loop done!" << std::endl;
}
void baz() {
this->runBar = false;
std::cout << "Field changed!" << std::endl;
}
private:
bool runBar;
};
And also given this main function:
int main(int argc, char* argv[]) {
Foo f;
f.bar();
f.baz();
return 0;
}
What happens when the call to Foo::baz() is made?
Thanks for the help!
Since you only have 1 thread of execution, and you do not have anything to change the while loop exit condition in the bar function, this code will loop forever. Your baz function will never be called.
Assuming you meant to call them from separate threads,
here is an example showing main modified to call the function from within a thread.
Foo is using a mutext to coordinate activity, like allowing the thread to finish printing before being terminated.
The join prevents termination of main from ending everything prematurely.
If you don't coordinate them in some way such as that, it would not possible to say with certainty what the sequence of events would be. Such is the nature of programming with multiple threads.
Either bar runs first in which case it prints, or else baz runs first in which case bar will not. Either is possible.
#include <iostream>
#include <mutex>
mutex aMutex; //<--
class Foo {
public:
Foo()
: runBar(true) {}
void bar() {
int i = 0;
while(this->runBar) {
aMutex.lock(); //<--
std::cout << "Loop " << i++ << std::endl;
aMutex.unlock(); //<--
}
std::cout << "Loop done!" << std::endl;
}
void baz() {
this->runBar = false;
aMutex.lock(); //<--
std::cout << "Field changed!" << std::endl;
aMutex.unlock(); //<--
}
private:
bool runBar;
};
#include <thread>
int main(int argc, char* argv[]) {
Foo f;
thread myThread { f.bar() }; //call it in a thread
f.baz();
myThread.join(); //<--
return 0;
}

How to use a std::function as a C style callback

How can I use a std::function in a function which expects a C-style callback?
If this is not possible, what is the next best thing?
Example:
// --- some C code I can not change ---
typedef void(*fun)(int);
void register_callback(fun f) {
f(42); // a test
}
// ------------------------------------
#include <functional>
#include <iostream>
void foo(const char* ptr, int v, float x) {
std::cout << ptr << " " << v << " " << x << std::endl;
}
int main() {
std::function<void(int)> myf = std::bind(&foo, "test", std::placeholders::_1, 3.f);
register_callback(myf); // <-- How to do this?
}
In most cases you can't.
But when you store a C style callback in your std::function, you can use the target() member function.
Long answer: sort of. You can write a C function to pass to the API that calls your std::function:
// --- some C code I can not change ---
typedef void(*fun)(int);
void register_callback(fun f) {
f(42); // a test
}
// ------------------------------------
#include <functional>
#include <iostream>
void foo(const char* ptr, int v, float x) {
std::cout << ptr << " " << v << " " << x << std::endl;
}
namespace {
std::function<void(int)> callback;
extern "C" void wrapper(int i) {
callback(i);
}
}
int main() {
callback = std::bind(&foo, "test", std::placeholders::_1, 3.f);
register_callback(wrapper); // <-- How to do this?
}

Equivalent to window.setTimeout() for C++

In javascript there's this sweet, sweet function window.setTimeout( func, 1000 ) ; which will asynchronously invoke func after 1000 ms.
I want to do something similar in C++ (without multithreading), so I put together a sample loop like:
#include <stdio.h>
struct Callback
{
// The _time_ this function will be executed.
double execTime ;
// The function to execute after execTime has passed
void* func ;
} ;
// Sample function to execute
void go()
{
puts( "GO" ) ;
}
// Global program-wide sense of time
double time ;
int main()
{
// start the timer
time = 0 ;
// Make a sample callback
Callback c1 ;
c1.execTime = 10000 ;
c1.func = go ;
while( 1 )
{
// its time to execute it
if( time > c1.execTime )
{
c1.func ; // !! doesn't work!
}
time++;
}
}
How can I make something like this work?
After C++11 came out, and if your are using c++11 supported compiler, you can use lambda, variadic template function and asynchronous thread to simulate javascript function in c++ easily.
Here is the code I wrote for setTimeOut, it is fully tested:
setTimeOut funtion's definition:
#include <windows.h>//different header file in linux
#include <future>
using namespace std;
template <typename... ParamTypes>
void setTimeOut(int milliseconds,std::function<void(ParamTypes...)> func,ParamTypes... parames)
{
std::async(std::launch::async,[=]()
{
Sleep(milliseconds);
func(parames...);
});
};
This function accepts variable arguments by using c+11's variadic template,
The code can show you how to use it:
#include <iostream>
#include <thread>
#include <string>
#include <functional>
#include <windows.h>
#include <future>
using namespace std;
int main()
{
std::mutex locker;
std::function<void()> func1 = [&]()
{
std::unique_lock<std::mutex> lk(locker);
std::cout << "func 1 is trigged:" << " no parameter" << std::endl;
lk.unlock();
};
std::function<void(int)> func2 = [&](int param)
{
std::unique_lock<std::mutex> lk(locker);
std::cout << "func 2 is trigged:" << " int: " << param <<std::endl;
lk.unlock();
};
std::function<void(int,std::string)> func3 = [&](int param1,std::string param2)
{
std::unique_lock<std::mutex> lk(locker);
std::cout << "func 3 is trigged:" << " int: " << param1 << "; string: " << param2 << std::endl;
lk.unlock();
};
for(int index=0;index<100;index++)
{
std::unique_lock<std::mutex> lk1(locker);
std::cout << "set timer for func 1" << std::endl;
lk1.unlock();
setTimeOut<>(1000,func1);
std::unique_lock<std::mutex> lk2(locker);
std::cout << "set timer for func 2" << std::endl;
lk2.unlock();
setTimeOut<int>(2000,func2,10000);
std::unique_lock<std::mutex> lk3(locker);
std::cout << "set timer for func 3" << std::endl;
lk3.unlock();
setTimeOut<int,std::string>(5000,func3,10000,"ddddd");
}
Sleep(10000000);
}
Make Callback::func of type void (*)(), i.e.
struct Callback
{
double execTime;
void (*func)();
};
You can call the function this way:
c1.func();
Also, don't busy-wait. Use ualarm on Linux or CreateWaitableTimer on Windows.
In C++ by itself, you're pretty limited. You need either a multithreaded OS, where you could use a sleep function (you can still have the program continue running with a separate thread), or you need a messaging system, like Windows.
The only other way I see that you can do something is to have a lot of calls scattered throughout the code that calls a function that returns true or false, depending on whether the time has elapsed. The function could, of course, be a callback, but you would still need to call it periodically.
I'm only fixing your code here, not thinking outside the box. The other answers already gave some pointers for that.
For better type safety, you should declare your callback pointer as follows:
// The function to execute after execTime has passed
void (*func)() ;
Then, call it as:
c1.func() ;
Another (better) answer would be to use the <functional> header in C++, and declare the function like so:
#include <functional>
function<void ()> func ;
// assign like
func = go ; //go is a function name that accepts 0 parameters
// and has return type void
// exec like
func() ;