std thread call template member function of template class: compiler error - c++

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;
}

Related

destructor is called twice for variant-based implementation

I have a variadic variant_callable class object that I want to use for a runtime polymorphism. Inside it uses a visitor pattern with std::variant.
However, I came by a rather strange behavior, that is object's destructor is called twice!.
#include <utility>
#include <variant>
#include <tuple>
namespace detail
{
template<typename... Impl>
class variadic_callable
{
public:
template<typename T>
constexpr explicit variadic_callable(T &&t) //
: varImpl_(std::forward<T>(t))
{}
variadic_callable(const variadic_callable &) = delete;
variadic_callable(variadic_callable &&) = delete;
template<typename... Args>
constexpr decltype(auto) operator()(Args &&...args) const
{
return std::visit(
[argsTuple = std::forward_as_tuple(args...)](const auto &visitor) {
return std::apply(
[&visitor](auto &&...args) {
return visitor(std::forward<decltype(args)>(args)...);
},
argsTuple);
},
varImpl_);
}
private:
std::variant<Impl...> varImpl_;
};
} // namespace detail
#include <string>
#include <iostream>
int main(int, char **)
{
struct callable
{
std::string str = "Long enough string to be allocated. Oceanic";
callable()
{
std::cout << "callable()" << std::endl;
}
void operator()(int i) const
{
std::cout << str << " " << i << '\n';
}
~callable()
{
std::cout << "~callable()" << std::endl;
}
};
{
std::cout << "expcected:\n";
const auto &c = callable();
c(815);
std::cout << "finished\n";
}
std::cout << '\n';
{
std::cout << "actual\n";
const auto &w = detail::variadic_callable<callable>{callable()};
w(815);
std::cout << "finished\n";
}
}
The output:
Program returned: 0
expcected:
callable()
Long enough string to be allocated. Oceanic 815
finished
~callable()
actual
callable()
~callable()
Long enough string to be allocated. Oceanic 815
finished
~callable()
https://godbolt.org/z/d849EaqbE
I guess an UB is in-place, but I can't spot it.
What I find the most peculiar is the fact that in the "actual" case std::string resources are not destroyed after the first destructor invocation!
variadic_callable's constructor is being passed an object of type callable. This is a temporary object that cannot be the same object as the one stored in the std::variant (no matter how it is passed).
The callable inside the std::variant must therefore be move-constructed from the passed temporary object. Both of these objects need to be eventually destroyed, requiring two calls to callable's destructor.
To prevent this you need to pass the arguments from which callable is supposed to be constructed to variadic_callable's constructor instead (here an empty list) and then pass these on to std::variants in-place constructor, i.e.
template<typename T, typename... Args>
constexpr explicit variadic_callable(std::in_place_type_t<T> t, Args&&... args) //
: varImpl_(t, std::forward<Args>(args)...)
{}
called as
detail::variadic_callable<callable>{std::in_place_type<callable>};
Here I copied std::variant's constructor design for the in-place overload.

How does std::thread store variadic arguments passed through its constructor?

Let's say I declare a thread with the following code:
#include <thread>
#include <iostream>
void printStuff(const char* c, long x) {
std::cout << x << " bottles of " << c << " on the wall\n";
}
int main()
{
std::thread t(printStuff, "beer", 900000000);
t.join();
}
How are the arguments printStuff, "beer," and 900000000 stored in the thread?
I know they are using a variadic template, where you first pass in a function and then a parameter pack of arguments. I am confused on how they forward all these template arguments, and then somehow call the inputted function with all the arguments when join or detach is called.
std::function has similar functionality where when you call std::bind it will store a function and its arguments inside the object, and then when you call the std::function object it will just execute the bound function with its arguments.
I am basically trying to implement my own version of std::function, for my own edification. I am curious how in C++ you would go about storing a function with a bunch of arbitrary parameters inside an object, and then having a method that would call the function with the passed in arguments.
I have looked at both the thread and std::function class, and both seem to be using tuples in some way to store their arguments. In a declaration of a tuple you have to specify what types you are storing in it:
std::tuple<int, std::string> tup;
How do std::function and thread get around this by storing their variadic arguments in tuples? Furthermore, how do they retrieve the function and call it with all of the arguments?
I am basically trying to implement my own version of std::function, for my own edification. I am curious how in C++ you would go about storing a function with a bunch of arbitrary parameters inside an object, and then having a method that would call the function with the passed in arguments.
std::function is a beast of a class so I won't pretend that this is anywhere close to as complete. std::function uses type erasure and small object optimization but I'll use polymorphism and store a base class pointer to a semi-anonymous implementation of a function wrapper to show how it can be done. I say semi-anonymous because it actually has a name, but it's defined locally inside the function that instantiates it. Storing the pointer (or the empty state) will be done in a std::unique_ptr<funcbase>.
The goal, as I've understood it, is to create a class with this basic interface:
template <class R, class... Args>
class fn_with_args<R(Args...)> {
public:
template <class F> fn_with_args(F&& f, Args&&... args);
R operator()();
};
That is, we need instances of fn_with_args<R(Args...)> to be able to store function pointers / functors that when invoked with the stored arguments returns R.
#include <functional>
#include <memory>
#include <tuple>
template <class> class fn_with_args; // not implemented
template <class R, class... Args>
class fn_with_args<R(Args...)> {
// an abstract base for cloneable function objects with an operator()() to call
struct funcbase {
virtual ~funcbase() = default;
virtual std::unique_ptr<funcbase> clone() const = 0;
virtual R operator()() = 0;
};
public:
// create empty "fn_with_args":
fn_with_args() noexcept = default;
fn_with_args(std::nullptr_t) noexcept {};
// copy ctor - if store contains a pointer to a funcbase,
// let it clone itself
fn_with_args(const fn_with_args& other) :
store(other.store ? other.store->clone() : nullptr) {}
// copy assignment
fn_with_args& operator=(const fn_with_args& other) {
if(this != &other) *this = fn_with_args(other); // copy+move
return *this;
}
// moving can be done by default:
fn_with_args(fn_with_args&& other) noexcept = default;
fn_with_args& operator=(fn_with_args&& other) noexcept = default;
// constructing and storing arguments
template <class F>
fn_with_args(F&& f, Args&&... args) {
// the semi-anonymous implementation that inherits from funcbase
// and stores both the function and the arguments:
struct funcimpl : funcbase {
funcimpl(F&& f, Args&&... a)
: func{std::forward<F>(f)}, args{std::forward<Args>(a)...} {}
// cloning via a base class pointer:
std::unique_ptr<funcbase> clone() const override {
return std::make_unique<funcimpl>(*this);
}
// the operator that will call `func` with the stored arguments:
R operator()() override { return std::apply(func, args); }
F func; // the actual function/functor
std::tuple<Args...> args; // and the stored arguments
};
// create and store an instance of the above semi-anonymous class:
store = std::make_unique<funcimpl>(std::forward<F>(f),
std::forward<Args>(args)...);
}
// The call interface. It'll dereference `store` and then call it which
// will call the overridden operator()() in the semi-anonymous `funcimpl`:
R operator()() {
if(store) return (*store)();
throw std::bad_function_call();
}
private:
std::unique_ptr<funcbase> store;
};
Example usage:
#include <iostream>
double foo(int x) {
return x * 3.14159;
}
int main() {
fn_with_args<int(double)> f1([](double d) -> int { return d; }, 3.14159);
std::cout << f1() << '\n';
fn_with_args<void()> f2; // create empty
//f2(); // would throw "bad_function_call" since it is "empty"
// populate it
f2 = fn_with_args<void()>([]{ std::cout << "void\n"; });
f2();
// call regular function:
fn_with_args<double(int)> f3(foo, 2);
std::cout << f3() << '\n';
// example with capture:
int v = 123;
f1 = fn_with_args<int(double)>([v](double d) -> int { return v * d; }, 3.14159);
std::cout << f1() << '\n';
// copying:
auto f11 = f1;
std::cout << f11() << '\n'; // calling the copy
}
Demo
you should store the params in std::tuple and invoke them using std::apply
#include <functional>
#include <tuple>
#include <vector>
template <class R>
class Function_Wrapper {
public:
template <typename Callable, typename... Args>
Function_Wrapper(Callable&& callable, Args&&... args)
: fn_([=, args = std::make_tuple(std::forward<Args>(args)...)]() {
return std::apply(callable, args);
}) {}
decltype(auto) run() {
// call our callable with the passed in arguments
return fn_();
}
decltype(auto) operator()() { return run(); }
private:
std::function<R()> fn_;
};
int add(int a, int b) { return a + b; }
int main() {
std::vector<Function_Wrapper<int>> f{{&add, 9, 30}, {&add, 1, 2}};
return f[0].run() + f[1]();
}
Here in Compiler Explorer

Safe Callback Provider (SFINAE, std::forward and overload resolution)

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.

passing lambda to a lambda callback parameter

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);
}

Store a function with arbitrary arguments and placeholders in a class and call it later

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!