I am using c++14 and I have a use case where I have to effectively do this:
template <typename F>
void foo (F&& fun)
{
auto l = []()->int
{
return 20;
};
fun(l);
}
int main ()
{
auto l = [] (auto& a)
{
std::cout << "Hello function: " << a() << std::endl;
// 'a' has to be copied to a queue optionally
};
foo(l);
}
But the foo() in-turn calls a million function - which uses the callback 'fun'. I cannot put all the code in header file. The simplest way to keep the definition of foo() and the called functions in dot cpp file might be to change foo() to
void foo (std::function< void(std::function<int(void)>) > fun)
But this is too inefficient, I dont want any memory allocation. Here there will be many, one of the creating the 'fun' and then for every call to 'fun(...)'. Now the outer std::function can be optimized by using something like the function_ref mentioned here.
https://vittorioromeo.info/index/blog/passing_functions_to_functions.html#fn_view_impl
But inner std::function, cannot be because it has to be 'optionally' copied to a queue. Now how can I make this work without a memory allocation - as close to the performance as using the template. [ One way is to have something like the std::function with a fixed internal storage.] But I have a feeling there exists a way by throwing more templates to achieve what I want. Or some way to change the interface to have more of less same effect.
Not sure if this is what you're looking for, but maybe it can be to some help.
#include <iostream>
#include <deque>
#include <memory>
struct lambdaHolderBase {
virtual int operator()() = 0;
};
template <typename T>
struct lambdaHolder : lambdaHolderBase {
lambdaHolder(T tf) : t(tf) {}
T& t;
int operator()() override { return t(); }
};
template <typename F>
void foo (F&& fun)
{
auto l = []()->int
{
return 20;
};
lambdaHolder<decltype(l)> l2(l);
fun(l2);
}
int main ()
{
auto l = [] (auto& a)
{
static std::deque<lambdaHolderBase*> queue;
std::cout << "Hello function: " << a() << std::endl;
queue.emplace_back( &a );
// 'a' has to be copied to a queue optionally
};
foo(l);
}
Related
I'm trying to add a line of code to the end of a lambda, similar to what the += operator does to std::string. For instance:
std::function<void()> foo = []() {
std::cout << "User defined code\n";
};
foo += [](){ std::cout << "I added this"; };
Desired output after calling foo():
User defined code
I added this
Of course this does not actually work as written.
Is this possible, or is there another way to effectively accomplish the same thing? Perhaps copying the lambda to another std::function then pass by value to a new lambda or something?
Edit:
I'm working with a class with a std::function member (foo) initialized with a lambda. Its member functions call it directly (with foo()) and I need to make it so that every time foo is called, an additional function is called as well. However this can be done would be great, as long as foo can still be called with foo();.
If you can change the type of the member, something like this might do it:
class Functions
{
public:
using Function = std::function<void()>;
Functions() = default;
template<typename Fn>
Functions(Fn f) { functions.push_back(f); }
Functions& operator+=(Function f)
{
functions.push_back(f);
return *this;
}
void operator()()
{
for (auto& f: functions)
{
f();
}
}
private:
std::vector<Function> functions;
};
Functions foo = []() { cout << "Hello"; }
foo += []() { cout << ", world!"; };
foo();
This solution is the closest I could come up with for your problem at hand:
class Lambdas
{
vector<function<void()>> lambdas;
public:
Lambdas(function<void()> lamb)
{
lambdas.push_back(lamb);
}
Lambdas& operator+=(function<void()> lamb)
{
lambdas.push_back(lamb);
return *this;
}
void operator()()
{
for (int i = 0; i<lambdas.size(); i++)
{
lambdas[i]();
}
}
};
Hope this helps.
So I am creating a type of event handler and I am in the process of writing an "Event Listener Wrapper", if you will.
The basic idea is this:
When you want to subscribe to an event, you create a function that should be called when the event fires. <-- already have that done (kinda, I'll explain)
You put this listener function into a wrapper to pass the function onto the dispatcher.
The dispatcher gets an event, finds the wrapper for you listener, and calls the underlying function with the parameter values set by the event.
I already have something working so long as the listeners all only accept one argument of my EventBase class. Then I have to type cast that into the proper event that the listener is passed.
What I want instead is for my listener functions to have "any" type of arguments, and store the function in a way that lets me call it with any arguments I want depending on the event fired. Each listener function would only ever receive one type of event, or the event it's self. This would allow me to not have to type cast each event in every listener, but instead the correct event would be passed.
I found a bit of code for this wrapper that is almost perfect, with a few minor issues that I can't seem to fix. I'll explain below.
Code by #hmjd:
#include <iostream>
#include <string>
#include <functional>
#include <memory>
void myFunc1(int arg1, float arg2)
{
std::cout << arg1 << ", " << arg2 << '\n';
}
void myFunc2(const char *arg1)
{
std::cout << arg1 << '\n';
}
class DelayedCaller
{
public:
template <typename TFunction, typename... TArgs>
static std::unique_ptr<DelayedCaller> setup(TFunction&& a_func,
TArgs&&... a_args)
{
return std::unique_ptr<DelayedCaller>(new DelayedCaller(
std::bind(std::forward<TFunction>(a_func),
std::forward<TArgs>(a_args)...)));
}
void call() const { func_(); }
private:
using func_type = std::function<void()>;
DelayedCaller(func_type&& a_ft) : func_(std::forward<func_type>(a_ft)) {}
func_type func_;
};
int main()
{
auto caller1(DelayedCaller::setup(&myFunc1, 123, 45.6));
auto caller2(DelayedCaller::setup(&myFunc2, "A string"));
caller1->call();
caller2->call();
return 0;
}
The first thing I did here was I had to replace std::unique_ptr with std::shared_ptr. Not sure why really. This almost works. In my use case, I need to store a method function (meaning bind needs to be passed the containing method object?), and at the time of storing the function I don't know what the argument value will be, thats up for the event to decide. So my adjustment is as follows:
class DelayedCaller
{
public:
template <typename TFunction, typename TClass>
static std::shared_ptr<DelayedCaller> setup(TFunction&& a_func,
TClass && a_class)
{
auto func = std::bind(std::forward<TFunction>(a_func),
std::forward<TClass>(a_class),
std::placeholders::_1);
return std::shared_ptr<DelayedCaller>(new DelayedCaller(func));
}
template <typename T>
void call( T v ) const { func_(v); }
private:
using func_type = std::function<void( )>;
DelayedCaller(func_type&& a_ft) : func_(std::forward<func_type>(a_ft)) {}
func_type func_;
};
For the sake of testing, I removed the parameter pack and replaced it with a direct parameter to the class object holding the function. I also gave the bind a placeholder for 1 argument (ideally replaced by the void call() function later).
It's created like this:
eventManager->subscribe(EventDemo::descriptor, DelayedCaller::setup(
&AppBaseLogic::getValueBasic,
this
));
Problem is: on this line:
return std::shared_ptr<DelayedCaller>(new DelayedCaller(func));
I get "no matching function for call to 'DelayedCaller::DelayedCaller(std::_Bind(AppBaseLogic*, std::_Placeholder<1>)>&)'
return std::shared_ptr(new DelayedCaller(func));"
This only happens when using the placeholder::_1. if I replace that with a known value of the correct type, it works, with the exception that the function gets called without any useful data of course.
So, I guess I need a way to store the function with placeholders that I don't know the type of?
Forgive me if I am getting names of things wrong. I am very new to c++, I have only started learning it the past few days.
**Edit: **
Ok, so I am just updating why I need to store functions like this.
I have a map in my event dispatcher that looks like this:
std::map< const char*, std::vector<DelayedCaller> > _observers;
I want to be able to call the function inside the "Delayed Caller" something like this:
void Dispatcher::post( const EventBase& event ) const
{
// Side Note: I had to do this instead of map.find() and map.at() because
// passing a "const char*" was not evaluating as equal to event.type() even
// though event.type() is also a const char*. So instead I am checking it
// myself, which is fine because it gives me a little more control.
std::string type(event.type());
for( auto const &x : _observers ) {
std::string type2(x.first);
if ( type == type2 ) {
auto&& observers = x.second;
for( auto&& observer : observers ) {
// event may be any descendant of EventBase.
observer.slot->call(event);
}
break;
}
}
}
My listeners currently look like this:
void AppBaseLogic::getValue(const EventBase &e) {
const EventDemo& demoEvent = static_cast<const EventDemo&>( e );
std::cout << demoEvent.type();
}
I am trying to store each function so that the argument may look like this:
void AppBaseLogic::getValue(const EventAnyDescendant &e) {
std::cout << e.type();
}
Hopefully that helps. Thank you all for taking the time to help me with this.
Side note on lambdas: Someone suggested them, I have know idea what they are or how to use them, but I am going to do some reaserch on them so see if that would make more sense. I am worried about maintainability with them though from what I have seen.
It isn't quite clear what your DelayedCaller is doing. If you refactor the code and get rid of it, you will get just this:
auto c1 = []() {myFunc1(123, 45.6);}; // or use bind, the result is exactly the same
auto c2 = []() {myFunc2("A string");};
vector<function<void()>> v {c1, c2};
v[0]();
v[1](); // ok
Now if you try to introduce the placeholder modification in this version, it becomes clear why it didn't work in the first place:
auto cSome = [](???) {getValueBasic(???)};
What do you replace the ??? with?
getValueBasic accepts some specific type of argument, and it will leak out into the cSome signature. No matter how many template wrappers you wrap it in, it will leak out into the signature of every wrapper up to and including the outermost one. bind and std::placeholders are not a magic wand capable of making it unhappen.
In other words, if you don't know the type of your function, you cannot call it (kind of obvious, isn't it?)
One way to type-erase the signature and have all callables to conform to the same type is to typecheck and typecast them at run time (a.k.a. dynamic_cast). Another one is double dispatch. Both methods are different incarnations of the same general idea of visitor. Google "the visitor pattern" for more info.
May be this suits you. using c++11
#include <iostream>
#include <functional>
#include <vector>
namespace test
{
std::vector<std::function<void()>> listeners;
template<typename F, typename... Args>
void add_listener(F call, Args&& ...args )
{
std::cout << "callback_dispatcher>" << __PRETTY_FUNCTION__ << "enter <<< " << std::endl;
auto invoke_me = [=]()mutable{
call(std::move(args)...);
};
listeners.push_back(invoke_me);
}
void dispatch_all()
{
for(auto func: listeners)
{
func();
}
}
}
int main()
{
std::cout << "Main entered..." << std::endl;
test::add_listener(
[](int a)
{
std::cout << "void(int) lambda dispatched with a = " << a << std::endl;
},
5
);
test::add_listener(
[](int a, std::string str)
{
std::cout << "void(int, string) lambda dispatched with a = " << a << ", str = " << str << std::endl;
},
10, "Hello World!"
);
test::dispatch_all();
std::cout << "Main exited..." << std::endl;
}
Output:
Main entered...
callback_dispatcher>void test::add_listener(F, Args&& ...) [with F = main()::<lambda(int)>; Args = {int}]enter <<<
callback_dispatcher>void test::add_listener(F, Args&& ...) [with F = main()::<lambda(int, std::__cxx11::string)>; Args = {int, const char (&)[13]}]enter <<<
void(int) lambda dispatched with a = 5
void(int, string) lambda dispatched with a = 10, str = Hello World!
Main exited...
Refer SO_QUESTION for why mutable and std::move is used when expanding args in a lambda.
Take a look at std::bind and perhaps std::mem_fn
The c+=11 version is able to do all sorts of clever transformations on your argument list to generate a function-like object.
Lambdas provide even more flexibility, of course, and you can mix them, mostly.
I see 2 main problems in your modified (method and placeholder) version of DelayedCaller
(1) now call() receive a parameter (of type T) so func_() is called with one parameter; but func_() remain defined of type std::function<void()>, so can't receive the parameter [this point is the reason of your "no matching function" error]
(2) if you templatize call(), receiving a parameter of with type T, it's necessary to templatize also the type of func_ that become std::function<void(T)>; so you have to templatize the full class.
Taking in count (1) and (2), and maintaining std::unique_ptr, I've rewritten your DelayedCaller as dcM1 (M for "method" and 1 for "1 parameter")
template <typename T>
class dcM1
{
public:
template <typename TFunction, typename TClass>
static std::unique_ptr<dcM1> setup (TFunction && a_func,
TClass && a_class)
{
auto func = std::bind(std::forward<TFunction>(a_func),
std::forward<TClass>(a_class),
std::placeholders::_1);
return std::unique_ptr<dcM1>(new dcM1(func));
}
void call( T v ) const
{ func_(v); }
private:
using func_type = std::function<void(T)>;
dcM1(func_type && a_ft) : func_(std::forward<func_type>(a_ft))
{ }
func_type func_;
};
and can be used as follows
auto cm1f = dcM1<int>::setup(&foo::func, &f);
auto cm1b = dcM1<long>::setup(&bar::func, &b);
cm1f->call(0);
cm1b->call(1L);
The following is a full working example
#include <iostream>
#include <string>
#include <functional>
#include <memory>
void myFunc1 (int arg1, float arg2)
{ std::cout << arg1 << ", " << arg2 << '\n'; }
void myFunc2 (char const * arg1)
{ std::cout << arg1 << '\n'; }
class dcVoid
{
public:
template <typename TFunction, typename... TArgs>
static std::unique_ptr<dcVoid> setup (TFunction && a_func,
TArgs && ... a_args)
{
return std::unique_ptr<dcVoid>(new dcVoid(
std::bind(std::forward<TFunction>(a_func),
std::forward<TArgs>(a_args)...)));
}
void call() const
{ func_(); }
private:
using func_type = std::function<void()>;
dcVoid(func_type && a_ft) : func_(std::forward<func_type>(a_ft))
{ }
func_type func_;
};
template <typename T>
class dcM1
{
public:
template <typename TFunction, typename TClass>
static std::unique_ptr<dcM1> setup (TFunction && a_func,
TClass && a_class)
{
auto func = std::bind(std::forward<TFunction>(a_func),
std::forward<TClass>(a_class),
std::placeholders::_1);
return std::unique_ptr<dcM1>(new dcM1(func));
}
void call( T v ) const
{ func_(v); }
private:
using func_type = std::function<void(T)>;
dcM1(func_type && a_ft) : func_(std::forward<func_type>(a_ft))
{ }
func_type func_;
};
struct foo
{ void func (int i) { std::cout << "foo func: " << i << std::endl; } };
struct bar
{ void func (long l) { std::cout << "bar func: " << l << std::endl; } };
int main ()
{
auto cv1 = dcVoid::setup(&myFunc1, 123, 45.6);
auto cv2 = dcVoid::setup(&myFunc2, "A string");
foo f;
bar b;
auto cm1f = dcM1<int>::setup(&foo::func, &f);
auto cm1b = dcM1<long>::setup(&bar::func, &b);
cv1->call();
cv2->call();
cm1f->call(0);
cm1b->call(1L);
}
Ok, So I know this has been sitting for a while. I've been doing heavy research into different event patterns trying to find something closer to what I was after. After pouring through everything, and with the advice of those who have left comments here, I have decided to use a Signal/Slot pattern, possibly the most widely used event pattern for C++. The way have have approached it is to have all of my "logic classes" (whether for a gui or for computation) keep a reference to a third "signal event holder class", which I am calling an event broker for simplicity. This is just about as good as I can get it. Any event that you might want to have can be added to this class, and it can be accessed and called from any class with a reference to the event broker. I found a pretty nice signal class made by Simon Schneegans, but I am actively trying to find/learn how to make something better (threadsafe, maybe faster?). If anyone is interested/looking for help like I was, you can find my super basic test case here:
https://github.com/Moonlight63/QtTestProject
Thanks!
Since function pointers need to know what arguments are supplied ahead of time I don't know how to do this.
Essentially I want a list of work. Each entry is a function to be called with specific arguments. I.e. I want to add foo(3, "abcd") to the work list, and then later bar(&h). That is, I don't know beforehand what types of functions will be added.
Later I will the iterate over this list and do the function calls specified.
Can this be implemented?
You're looking for std::function and either lambdas, or std::bind.
std::function is a wrapper for an arbitrary callable. You can store anything in it on which you can call operator() with the appropriate arguments.
One thing you can store in it are lambdas: you'd encapsulate the call and arguments into a non-argument lambda and call that.
Another thing you can store is the result of std::bind. std::bind is effectively a metafunction: it takes a function f and arguments as input, and returns a function object whose invocation results in invoking f on the arguments.
Here's how you could apply this to your case. The common setup:
std::vector<std::function<void()>> workList;
fillWorkList(workList);
for (auto& f : workList)
f();
And here are two possible implementations of fillWorkList. One with std::bind:
void fillWorkList(std::vector<std::function<void()>>& workList)
{
workList.push_back(std::bind(foo, 3, "abcd"));
workList.push_back(std::bind(bar, &h));
}
And one with lambdas:
void fillWorkList(std::vector<std::function<void()>>& workList)
{
workList.push_back([]() { foo(3, "abcd"); });
workList.push_back([]() { bar(&h); });
}
A std::function<void()> represents something that can be invoked, and returns nothing.
The clearest thing to store in it is a lambda.
std::function<void()> f = []{ foo(3, "abcd"); };
stores "call foo( 3, "abcd" ); in the std::function called f.
We can build a list of them -- a std::deque or std::vector -- and call them at a later time.
You can capture state in a lambda by putting what you want to capture within the []s:
std::function<void()> g = [h]{ bar(&h); };
This copies h into the lambda, then calls bar with a pointer to h. Sometimes you'll want h to be mutable:
std::function<void()> g = [h]()mutable{ bar(&h); };
You can also have lambdas that store references to variables. This is dangerous, as you are responsible for lifetime, and if you are storing the lambdas within std::functions then storing those in a container, lifetime may not be simple.
In C++14 you can even put expressions in the []s.
std::function<void()> behaves like a value. You invoke it with (), just like calling a function with signature void().
Using std::bind instead of lambdas is technically possible, but std::bind has many strange quirks and the code generated is usually less clear and errors are almost always unreadable. Don't do it.
You can also do this with a custom function object.
struct custom {
std::string s;
void operator()() const {
foo( 3, s );
}
};
Then std::function<void()> f = custom{ "abcd" }; is another way to say you'll invoke foo with 3, std::string("abcd") later when you f() on f.
Here is a solution, using a parameter pack, and perfect forwarding that allows for add(foo, 3, "abcd") to be used:
#include <functional>
#include <string>
#include <iostream>
#include <vector>
#include <utility>
void foo(int val, std::string text) { std::cout << val << '\t' << text << '\n'; }
void bar(int* ptr) { std::cout << *ptr << '\n'; }
class Worklist {
public:
template <typename ...Args>
void add(Args&&... args) {
worklist.push_back(std::bind(std::forward<Args>(args)...));
}
void do_all()
{
for(auto& i : worklist) {
i();
}
}
std::vector<std::function<void(void)>> worklist;
};
int main()
{
int h{9};
Worklist worklist;
worklist.add(foo, 3, "abcd");
worklist.add(bar,&h);
worklist.do_all();
}
It is possible to write a class that will accept lambdas as the tasks without using std::bind or std::function.
Here, a std::unique_ptr is used to store each of the lambdas:
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <utility>
void foo(int val, std::string text) { std::cout << val << '\t' << text << '\n'; }
void bar(int* ptr) { std::cout << *ptr << '\n'; }
class Generic_Callable {
public:
~Generic_Callable() = default;
virtual void call() = 0;
};
template <typename T>
class MyCallable : public Generic_Callable {
public:
MyCallable(T &&t) : ptr{std::make_unique<T>(std::move(t))} {}
void call() override
{
(*ptr)();
}
std::unique_ptr<T> ptr;
};
class Worklist {
public:
template <typename T>
void add(T &&t)
{
worklist.push_back(std::make_unique<MyCallable<T>>(std::move(t)));
}
void do_all() {
for(auto& i : worklist)
i->call();
}
std::vector<std::unique_ptr<Generic_Callable>> worklist;
};
int main()
{
int h{9};
Worklist worklist;
worklist.add([]() {foo(3, "abcd"); });
worklist.add([&h]() {bar(&h); });
worklist.do_all();
}
I have a scope guard like class (this is the simplified test case):
template<void(*close)()>
struct Guard1
{
template<typename O>
Guard1(O open) { open(); }
~Guard1() { close(); }
};
void close() { std::cout << "close g1\n"; }
int main()
{
Guard1<close> g1 = [](){ std::cout << "open g1\n"; };
}
I modified it such that the close expression can also be given as a lambda:
class Guard2
{
std::function<void()> close;
public:
template<typename O, typename C>
Guard2(O open, C close) : close(close)
{
open();
}
~Guard2() { close(); }
};
int main()
{
Guard2 g2(
[](){ std::cout << "open g2\n"; },
[](){ std::cout << "close g2\n"; });
}
However I had to introduce an extra field const std::function<void()>& close; to pass the lambda from the constructor to the destructor.
Is there a way to avoid this extra field while still keeping the lambda (and a nice syntax when used as well)?
Since you want to use it only as ScopeGuard - then you can be sure that const reference or rvalue reference to your close() are valid. You need a member or base class as in other answer - but this is not very big difference. But you can have it as rvalue reference to your lambda, not to std::function which is of quite big performance cost:
template <class Close>
class ScopeGuard {
public:
template <typename Open>
ScopeGuard(Open&& open, Close&& close)
: close(std::forward<Close>(close))
{
open();
}
ScopeGuard(ScopeGuard&& other) : close(std::move(other.close))
{}
~ScopeGuard()
{
close();
}
private:
Close&& close;
};
To make it easier to use - have this make function:
template <class Open, class Close>
auto makeScopeGuard(Open&& open, Close&& close)
{
return ScopeGuard<Close>(std::forward<Open>(open),
std::forward<Close>(close));
}
And usage:
#include <iostream>
using namespace std;
int main()
{
int i = 0;
auto scope = makeScopeGuard([&i]{cout << "Open " << i++ << "\n";},
[&i]{cout << "Close " << i++ << "\n";});
cout << "Body\n";
}
Output:
Open 0
Body
Close 1
I verified it works for gcc and clang, C++14 without errors/warnings.
It's generally not possible. Unlike a function pointer, a lambda can capture and therefore contain run-time state. True, your lambda does not, and therefore can be converted to a function pointer, but that doesn't make it a template argument.
If you can accept a bit of cheating: stuff the lambda into a base class instead of a field:
#include <iostream>
template<typename Base>
struct Guard1 : public Base
{
template<typename O>
Guard1(O open, Base base ) : Base(base) { open(); }
Guard1(Guard1 const& rhs) : Base(static_cast<Base const&>(rhs)) { }
~Guard1() { (*this)(); }
};
template<typename O, typename C>
Guard1<C> makeGuard(O o, C c) { return Guard1<C>(o,c); }
int main()
{
auto g1 = makeGuard([](){ std::cout << "open g1\n"; },
[](){ std::cout << "close g1\n"; } );
}
Is there a way to avoid this extra field while still keeping the lambda (and a nice syntax when used as well)?
Yes: If you observe, there is nothing to be gained by passing the open function to your scope guard (therefore the Single Responsibility Principle states you should not have it there).
You should also pass the function as a runtime parameter, not a template parameter. This will allow for more natural syntax in client code.
You should make the type independent on the template type. This will also make for more natural syntax in client code.
You should ensure the destructor does not throw.
class Guard final
{
public:
Guard1(std::function<void()> at_scope_exit)
: f_(std::move(at_scope_exit))
{
}
~Guard1() noexcept { try{ f_(); } catch(...) {} }
private:
std::function<void()> f_;
};
Your client code should then look like this:
int x()
{
operation.begin_transaction();
Guard commit{ [&operation](){ operation.commit_transaction(); } };
// do things & stuff here
}
Maybe you can use the answer of this question.
Hope I am not wrong, but if it was possible to use the constructor's pointer, you could pass it to type_traits (look at the first answer in that question), and get the second argument which would be close function, and then you could alias it.
Since it is not possible to get the constructor's pointer, maybe you can use an other member function to initialize your object ?
Here is the code. It does not compile in vs2013, but does compile in gcc4.8
error C2665: 'std::thread::thread' : none of the 4 overloads could convert all the argument types
Since I am using vs2013, can anyone provide workaround?
#include <iostream>
#include <thread>
template<typename T>
class TestClass
{
public:
TestClass(){};
~TestClass(){};
T t;
template<typename U>
void fun(U u)
{
std::cout << "fun: " << u << '\n';
}
};
int main()
{
TestClass<double> A;
auto aaa = std::thread(&TestClass<double>::fun<int>, &A, 1);
}
You could simply use a lambda rather than monkeying with member function pointers:
auto aaa = thread( [&]{ A.fun(1); } );
aaa.join();
There is another way you can achieve above problem,If you would mind !
First just look explicit constructor of thread object:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
f - Universal reference for function object.
args - variadic arguments for function(functor) f.
(I am not going to explain deeper and deeper about variadic calling used here).
So now we know we can deal with functors therefore,
Define a functor(function object) like below :
template<typename T>
class TestClass
{
public:
TestClass(){};
~TestClass(){};
T t;
template<typename U>
void operator()(U u1,U u2){
std::cout << "fun: " << u1*u2 << '\n';
}
};
int main()
{
TestClass<double> A;
auto aaa = std::thread(A,1,100);// calling functor A(1,100)
aaa.join()
//or if you can move object from main thread to manually created thread aaa ,it's more elegant.
auto aa = std::thread(std::move(A),1,100);
aa.join();
A(1, 99);
system("Pause");
return 0;
}
//Please notice here I've not used any locker guard system.
If you use static function you don't have to bind respective instance each time this may change your expected run-time behavior therefore you have to managed,
template<typename U>
static void fun(U u)
{
std::cout << "fun: " << u << '\n';
}
then invoke the function,
int main()
{
TestClass<double> A;
auto aaa = std::thread(&TestClass<double>::fun<int>, 1);
system("Pause");
return 0;
}