myNameSpace::functionName(this, {"abc", "abc1"}); // working fine
working fine, but
std::thread(myNameSpace::functionName<ClassName>(this, {"abc", "abc1"}));
//error: invalid use of void expression.
Please suggest me what I am missing here. or how to do it.
namespace myNameSpace {
template<typename T>
void functionName(T* cm, std::initializer_list<std::string_view> args) { ... }
}
First, that is not how you start a thread. You are calling it, and passing the result as an argument to start the thread. But, void is not a valid argument for starting a thread, nor is it indeed any sort of useful expression in any sense.
You'd be writing something like this instead:
std::thread(&myNameSpace::functionName<ClassName>, this, {"abc", "abc1"});
Your next problem is that there is no facility in the language for the compiler to deduce what you mean by {"abc", "abc1"} there. With a direct function call to functionName, it can work it out, because the function call machinery knows what the candidate overloads are, but that is just not the case with this "broken down" construction.
It's possible to fix that by specifying the type:
std::thread(&myNameSpace::functionName<ClassName>, this, std::initializer_list<std::string_view>{"abc", "abc1"});
However, I recommend you just pass (and accept) a std::vector<std::string_view> instead. It'll be much easier and much simpler.
std::thread receives a callable as first parameter, you sent it void (The invoke result of myNameSpace::functionName).
What you need to do is
std::thread(myNameSpace::functionName<ClassName>, this, std::initializer_list<std::string_view>({"abc", "abc1"})));
Note that explicit casting to std::initializer_list is required, as std::initializer_list is non deductible type.
For threads you need to provide function reference and arguments parameters in arguments list like following:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
in your case you have to provide the arguments as following:
std::thread(myNameSpace::functionName<ClassName>,this, std::initializer_list<std::string_view>({"abc", "abc1"}));
Related
here is function to register.
template <typename ReqT, typename RespT>
bool RegisterCmdHandler(int cmd_id, std::function<int(int, const ReqT&, RespT&)> sync_handler) {
// ... do something with sync_handler and register it for later callback
return true;
}
and a specific handler to register:
int SomeHandler(int id, const Foo& req, Bar& resp) {
// ... specific logic
}
now I want to apply the Handler to Register Function, compiler complains
RegisterCmdHandler(1, SomeHandler); // ERROR, compiler can not deduce
while specificly write out the type is OK:
RegisterCmdHandler<Foo, Bar>(1, SomeHandler); // OK, compiler can deduce
but the latter has ugly API. How can I get the first on work?
How can I get the first on work?
Add an overload for plain function pointers:
template <typename ReqT, typename RespT>
bool RegisterCmdHandler(int cmd_id, int(*sync_handler)(int, const ReqT&, RespT&)) {
std::function<int(int, const ReqT&, RespT&)> sync_handler2(sync_handler);
return RegisterCmdHandler(cmd_id, sync_handler2);
}
How can I get the first on work?
I see some ways.
(1) If you can modify the RegisterCmdHandler() function and you don't need to know, inside it, what types ReqT and RestT are, I suggest you to avoid at all std::function and accept sync_handler as a simple template type.
I mean
template <typename F>
bool RegisterCmdHandler (int cmd_id, F sync_handler) {
// ... do something with sync_handler
return true;
}
This is a very flexible solution because F can be a function, a function pointer, a std::function, a lambda (also a generic lambda, so this solution is more flexible than using std::function), another type of class/struct with an operator(), a value returned from a std::bind. In short: a generic callable.
(2) If you can modify the RegisterCmdHandler() function but you need to know (and use) the ReqT and RestT, you can follows the plain function pointer way (see Maxim Egorushkin's answer for the syntax). Unfortunately this works with function pointers only and doesn't works (by example) when sync_handler is a lambda.
(3) If you can't modify RegisterCmdHandler() but you can use C++17, you can use std::function deduction guides and call the function as follows
RegisterCmdHandler(1, std::function{SomeHandler});
or, maybe better if you have to call it in different places, call it through a converter
template <typename F>
auto CallRegisterCH (int cmd_if, F && func)
{ return RegisterCmdHandler(cmd_if, std::function{std::forward<F>(func)}); }
calling it as follows
CallRegisterCH(1, SomeHandler);
(4) if you can't modify RegisterCmdHandler() and you have to use C++11 or C++14... well... explicating the template types
RegisterCmdHandler<Foo, Bar>(1, SomeHandler);
seems to me the better way.
Other ways you can explicit the std::function
std::function<int(int, Foo const &, Bar &)> sh{ SomeHandler };
RegisterCmdHandler(1, sh);
but seems to me almost the same thing.
I need to get the address of an overloaded template function that involves SFINAE. A good example of this scenario would be boost::asio::spawn found here...
https://www.boost.org/doc/libs/1_70_0/doc/html/boost_asio/reference/spawn.html
How would I find the address of this particular instance...
template<
typename Function,
typename Executor>
void spawn(
const Executor & ex,
Function && function,
const boost::coroutines::attributes & attributes = boost::coroutines::attributes(),
typename enable_if< is_executor< Executor >::value >::type* = 0);
I've unsuccessfully tried this...
using Exec = boost::asio::io_context;
using Func = std::function<void(boost::asio::yield_context)>;
void (*addr)(Exec, Func) = boost::asio::spawn;
boost::asio::spawn is not a function. It is a function template. It's a blueprint from which functions can be created. There's no way to get a pointer to a function template because it's a purely compile-time construct.
boost::asio::spawn<Func, Exec> is a function overload set, but it has no overload that matches the signature void(Exec,Func). Remember, default function arguments are just syntactic sugar. Those arguments are still part of the function's signature.
Those two issues make getting a pointer to boost::asio::spawn hard and ugly. It would be much easier to use a lambda. A lambda will let you preserve type deduction and take advantage of the default arguments:
auto func = [](auto&& exec, auto&& func) {
boost::asio::spawn(std::froward<decltype(exec)>(exec),
std::forward<decltype(func)>(func));
};
Even if you absolutely need a function pointer, a lambda is still probably the way to go. You lose parameter type deduction, but can still take advantage of the function's default arguments:
void(*addr)(const Exec&, Func) = [](const Exec& exec, Func func) {
boost::asio::spawn(exec, std::move(func));
};
This works because captureless lambdas can be converted to raw function pointers.
If you really, absolutely need a pointer directly to one of the spawn instantiations for some reason, you can get it, but it's not pretty:
using Exec = boost::asio::io_context::executor_type;
using Func = std::function<void(boost::asio::yield_context)>;
void(*addr)(const Exec&, Func&, const boost::coroutines::attributes&, void*) = boost::asio::spawn<Func&, Exec>;
You lose a lot in doing so though. Not only do you lose argument type deduction and the default arguments, you also lose the ability to pass both lvalues and rvalues to the function since you no longer have a deduced context for forwarding references to work in. I've to get a pointer to the instantiation accepting an lvalue-reference to the function. If you want it to accept rvalue-references instead, use
void(*addr)(const Exec&, Func&&, const boost::coroutines::attributes&, void*) = boost::asio::spawn<Func, Exec>;
Also note that this function takes four parameters. Call it with, i.e.
addr(my_io_context.get_executor(), my_function, boost::coroutines::attributes{}, nullptr);
Example
Tried to put this solution as an edit in the question where it'd be visible right off, but the moderators seem to think it's better to force a reader through to here...
using Exec = boost::asio::io_context;
using Func = std::function<void(boost::asio::yield_context)>;
using Attr = boost::coroutines::attributes;
void (*addr)(const Exec&,
Func&&,
const Attr&,
typename enable_if< is_executor< Executor >::value>::type*
) = boost::asio::spawn<Func, Exec>;
Yes, ugly but not too too bad.
I've a code:
class cabc{
public:
void pr()
{
cout<<"abcdef";
}
};
int main()
{
cabc cap;
auto f = async(cap.pr);
f.get();
return 0;
}
This code is not working. I know the same thing can be done using:
auto f = async(&cabc::pr,cap);
This is working. But why the first approach is not working?
cap.pr is an incomplete member function call expression. You must follow it with parentheses containing the appropriate function arguments to make a valid C++ expression.
You can't therefore pass cap.pr to std::async or any other function.
To pass a member function to std::async you need to use the syntax you found:
auto f=std::async(&capc::pr,cap);
Though in this case, you need to be aware that the cap object is copied. You could also use
auto f=std::async(&capc::pr,&cap);
to just pass a pointer to cap.
If the pointer-to-member-function syntax is unwelcome then you can use a lambda:
auto f=std::async([&]{cap.pr();});
This isn't quite the same: it doesn't pass the member function pointer and object pointer to std::async, it passes a lambda object containing a reference to cap that calls its pr member function directly. However, the result is essentially the same.
Have a look at the function signature for async:
template< class Function, class... Args>
std::future<typename std::result_of<Function(Args...)>::type>
async( Function&& f, Args&&... args );
(from cppreference)
It should be apparent that, firstly, whatever Function&& is, it can't be the case that cap.pr and &cabc::pr are both of that type.
More precisely, though, Function&& is supposed to be an rvalue-reference to a function pointer. &cabc::pr is just the syntax for a pointer-to-member-function, and because it's a member function, a pointer to the object itself needs to be the first argument. If cap.pr were a C-style function pointer, then your first sample might work.
Honestly, I'm not sure why your second sample works since you're not passing in a pointer to your object.
There are a number of other answers to similar questions. For example: How to, in C++11, use std::async on a member function?
When doing:
std::vector<int> vec;
int number = 4;
boost::thread workerThread(&Method, number, vec)
given a method:
template<typename T>
void Method(int n, std::vector<T> & vec)
{
//does stuff
}
Why do I have to manually do:
boost::thread workerThread(&Method, number, boost::ref(vec))?
Why does it not automatically pass it by reference?
Edit:: so would it be possible theoretically for boost::thread to do some macro-meta-programming to adjust this since C++ has nothing in the way of built in reflection/introspection.
So is a major part of boost / C++ in general passing meta-information around?
Because the boost::thread object cannot determine the signature of Method.
He only knows the types of the arguments being passed in and will forward them to the provided function. If the types don't match you get a nice complicated error message at the place where boost::thread attempts to call the function.
When looking at the types of the arguments, it is impossible to differ between pass-by-reference and pass-by-value as they look the same from the caller's side. Or from a more formal perspective: In template argument deduction T& will decay to T.
Only by providing the explicit boost::ref on the caller's side boost::thread will be able to correctly identify the type as a reference type.
Probably the workerThread might be trying to deduce the types in signaure of Method , which it cant deduce from &Method, itself.
I recently ran into a bug in my code when using boost::bind.
From the boost::bind docs:
The arguments that bind takes are copied and held internally by the returned function object.
I had assumed that the type of the copy that was being held was based on the signature of the function. However, it is actually based on the type of the value passed in.
In my case an implicit conversion was happening to convert the type used in the bind expression to the type received by the function. I was expecting this conversion to happen at the site of the bind, however it happens when the resulting function object is used.
In retrospect I should have been able to figure this out from the fact that using boost::bind gives errors when types are not compatible only at the call site, not the bind site.
My question is:
Why does boost::bind work this way?
It seems to give worse compiler error messages
It seems to be less efficient when implicit conversion happens and there are multiple calls to the functor
But given how well Boost is designed I'm guessing there is a reason. Was it behavior inherited from std::bind1st/bind2nd? Is there a subtle reason why this would be hard/impossible to implement? Something else entirely?
To test that second theory I wrote up a little code snippet that seems to work, but there may well be features of bind I haven't accounted for since it's just a fragment:
namespace b = boost;
template<class R, class B1, class A1>
b::_bi::bind_t<R, R (*) (B1), typename b::_bi::list_av_1<B1>::type>
mybind(R (*f) (B1), A1 a1)
{
typedef R (*F) (B1);
typedef typename b::_bi::list_av_1<B1>::type list_type;
return b::_bi::bind_t<R, F, list_type> (f, list_type(B1(a1)));
}
struct Convertible
{
Convertible(int a) : b(a) {}
int b;
};
int foo(Convertible bar)
{
return 2+bar.b;
}
void mainFunc()
{
int x = 3;
b::function<int()> funcObj = mybind(foo, x);
printf("val: %d\n", funcObj());
}
Because the functor may support multiple overloads, which may give different behaviours. Even if this signature could be resolved when you knew all the arguments (and I don't know if Standard C++ can guarantee this facility) bind does not know all the arguments, and therefore it definitely cannot be provided. Therefore, bind does not possess the necessary information.
Edit: Just to clarify, consider
struct x {
void operator()(int, std::vector<float>);
void operator()(float, std::string);
};
int main() {
auto b = std::bind(x(), 1); // convert or not?
}
Even if you were to reflect on the struct and gain the knowledge of it's overloads, it's still undecidable as to whether you need to convert the 1 to a float or not.
There are different cases where you need the arguments to be processed at the call site.
The first such example is calling a member function, where you can either have the member called on a copy of the object (boost::bind( &std::vector<int>::push_back, myvector)) which most probably you don't want, or else you need to pass a pointer and the binder will dereference the pointer as needed (boost::bind( &std::vector<int>::push_back, &myvector )) --Note both options can make sense in different programs
Another important use case is passing an argument by reference to a function. bind will copy performing the equivalent to a pass-by-value call. The library offers the option of wrapping arguments through the helper functions ref and cref, both of which store a pointer to the actual object to be passed, and at the place of call they dereference the pointer (through an implicit conversion). If the conversion to the target type was performed at bind time, then this would be impossible to implement.
I think this is due to the fact that bind has to work with any callable entity, be it a function pointer, std::function<>, or your own functor struct with operator(). This makes bind generic on any type that can be called using (). I.e. Bind's implicit requirement on your functor is just that it can be used with ()
If bind was to store the function argument types, it would have to somehow infer them for any callable entity passed in as a type parameter. This would obviously not be as generic, since deducing parameter types of an operator() of a passed-in struct type is impossible without relying on the user to specify some kind of typedef (as an example). As a result the requirement on the functor (or concept) is no longer concrete/simple.
I am not entirely sure this is the reason, but it's one of the things that would be a problem.
EDIT: Another point as DeadMG mentions in another answer, overloads would create ambiguities even for standard function pointers, since the compiler would not be able to resolve the functor type. By storing the types you provide to bind and using (), this problem is also avoided.
A good example would binding "std::future"s to some ordinary function taking ordinary types:
Say I want to use an ordinary f(x,y) function in an incredibly asynchronous way. Namely, I want to call it like "f(X.get(), Y.get())". There's a good reason for this- I can just call that line and f's logic will run as soon as both inputs are available (I don't need separate lines of code for the join). To do this I need the following:
1) I need to support implicit conversions "std::future<T> -> T". This means std::future or my custom equivalent needs a cast operator:
operator T() { return get(); }
2) Next, I need to bind my generic function to hide all its parameters
// Hide the parameters
template<typename OUTPUT, typename... INPUTS>
std::function<OUTPUT()> BindVariadic(std::function<OUTPUT(INPUTS...)> f,
INPUTS&&... in)
{
std::function<OUTPUT()> stub = std::bind( f, std::forward<INPUTS>(in)...);
return stub;
}
With a std::bind that does the "std::function<T> -> T" conversion at call time, I only wait for all the input parameters to become available when I ACTUALLY CALL "stub()". If it did the conversion via operator T() at the bind, the logic would silently force the wait when I actually constructed "stub" instead of when I use it. That might be fatal if "stub()" cannot always run safely in the same thread I built it.
There are other use cases that also forced that design choice. This elaborate one for async processing is simply the one I'm personally familiar with.