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.
Related
I've noticed that it's impossible to pass a non-const reference as an argument to std::async.
#include <functional>
#include <future>
void foo(int& value) {}
int main() {
int value = 23;
std::async(foo, value);
}
My compiler (GCC 4.8.1) gives the following error for this example:
error: no type named ‘type’ in ‘class std::result_of<void (*(int))(int&)>’
But if I wrap the value passed to std::async in std::reference_wrapper, everything is OK. I assume this is because std::async takes it's arguments by value, but I still don't understand the reason for the error.
It's a deliberate design choice/trade-off.
First, it's not necessarily possible to find out whether the functionoid passed to async takes its arguments by reference or not. (If it's not a simple function but a function object, it could have an overloaded function call operator, for example.) So async cannot say, "Hey, let me just check what the target function wants, and I'll do the right thing."
So the design question is, does it take all arguments by reference if possible (i.e. if they're lvalues), or does it always make copies? Making copies is the safe choice here: a copy cannot become dangling, and a copy cannot exhibit race conditions (unless it's really weird). So that's the choice that was made: all arguments are copied by default.
But then, the mechanism is written so that it actually fails to then pass the arguments to a non-const lvalue reference parameter. That's another choice for safety: otherwise, the function that you would expect to modify your original lvalue instead modifies the copy, leading to bugs that are very hard to track down.
But what if you really, really want the non-const lvalue reference parameter? What if you promise to watch out for dangling references and race conditions? That's what std::ref is for. It's an explicit opt-in to the dangerous reference semantics. It's your way of saying, "I know what I'm doing here."
std::async (and other functions that do perfect forwarding) look at the type of the argument that you pass to figure out what to do. They do not look at how that argument will eventually be used. So, to pass an object by reference you need to tell std::async that you're using a reference. However, simply passing a reference won't do that. You have to use std::ref(value) to pass value by reference.
The issue itself is only marginally related to std::async(): When defining the result of the operation, std::async() uses std::result_of<...>::type with all its arguments being std::decay<...>::type'ed. This is reasonable because std::async() takes arbitrary types and forwards them to store them in some location. To store them, values are needed for the function object as well as for the arguments. Thus, std::result_of<...> is used similar to this:
typedef std::result_of<void (*(int))(int&)>::type result_type;
... and since int can't be bound to an int& (int isn't an lvalue type was is needed to be bound to int&), this fails. Failure in this case means that std::result_of<...> doesn't define a nested type.
A follow-up question could be: What is this type used to instantiate std::result_of<...>? The idea is that the function call syntax consisting of ResultType(ArgumentTypes...) is abused: instead of a result type, a function type is passed and std::result_of<...> determines the type of the function called when that function type is called with the given list of arguments is called. For function pointer types it isn't really that interesting but the function type can also be a function object where overloading needs to be taken into account. So basically, std::result_of<...> is used like this:
typedef void (*function_type)(int&);
typedef std::result_of<function_type(int)>::type result_type; // fails
typedef std::result_of<function_type(std::reference_wrapper<int>)>::type result_type; //OK
I have been trying to pass an interpolation function by reference as an argument to another function but I keep getting the following error:
error: could not convert '&AmrCoreAdv::interp_reta_from_R' from 'double (AmrCoreAdv::*)(double)' to 'std::function<double(double)'
There is a header file called AmrCoreAdv.H where the interpolation function is declared as double interp_reta_from_R(double R) and it is defined in another file. The interpolation function is passed as an argument to the state_rhs function and is called as follows:
state_rhs(i, j, k, rhs_fab, state_fab, eta, dx[0], dx2, deta, eta2, two_over_eta, three_over_eta, e2_over_8pi2, &interp_reta_from_R);
The function state_rhs takes in the following arguments:
state_rhs(int i, int j, int k,
amrex::Array4<amrex::Real> const& rhs_fab,
amrex::Array4<amrex::Real const> const& state_fab,
const amrex::Real eta,
const amrex::Real _dx,
const amrex::Real dx2,
const amrex::Real d_eta,
const amrex::Real eta2,
const amrex::Real two_over_eta,
const amrex::Real three_over_eta,
const amrex::Real e2_over_8pi2,
std::function<double (double)> interp_reta_from_R)
I am relatively new to C++ and am lost as to how to proceed. I have tried using typedef and some other ways of defining the type of the interp_reta_from_R function as an argument in the state_rhs function but to no avail. I would really appreciate some guidance on this. Please let me know if you would require any additional information for debugging this issue. Thank you!
A member function is not like a free function - it has a different type which includes the class, and it can't be called without an instance of the class.
The simplest thing is to pass a lambda function instead, capturing the object that should get its member called.
Assuming that the function is a member of *this, replace the pointer-to-member with
[this](double d) { return interp_reta_from_R(d); }
Pointer to member is not a regular pointer, it needs to come with its object.
Consider the following code:
struct S
{
double f(double);
};
//whatever
S s;
s.f(3.14);
The mental model for the call to f can be sth like the following one (this is just a mental model, it has nothing to do with the standard, calling convention etc.):
f(&s, 3.14); //s address
For that reason, in order to transform a member function into a free function, it's object argument needs to be bound to it.
Modern C++ (C++11 onwards) has two means of doing this: std::bind or lambda expressions. For pre-C++11 one can look-up boost::bind which plays essentially the same role as its std counterpart.
Note that lambdas (since C++11) are somewhat limited when it comes to move-only types, which means one might be stuck with bind; should technical limitations not be the case use whatever suits your needs, taste and code conventions.
Also, note that object might be provided either by value (giving the created function object copy semantics) or reference/address. In the latter case, make sure the functor does not outlive the objects it is supposed to be referring to.
Example:
#include <functional>
struct S
{
double f(double) {return{};}
};
void ff(std::function<double(double)>){}
int main(int, char*[])
{
S s;
ff(std::bind(&S::f, s, std::placeholders::_1)); //bind by value
ff(std::bind(&S::f, &s, std::placeholders::_1)); //bind by address
ff([&s](double x){return s.f(x);}); //lambda with capture by reference
ff([s](double x)mutable{return s.f(x);}); //lambda capturing by value. Note mutable; lambdas by default capture by value as const objects!
}
DEMO: https://godbolt.org/z/M9sGj36jq
Why std::invoke does not work with a pointer to member which is a function object with arguments? Like this:
struct MyClass
{
std::function<void(int)> functor{ [](int arg) { printf("%d\n", arg); } };
};
int main()
{
MyClass mc;
std::invoke(&MyClass::functor, mc, 110);
}
Prints : 'std::invoke': no matching overloaded function found.
I checked this in Visual C++ and g++.
Moreover, std::is_invocable_v<decltype(&MyClass::functor), MyClass, int> claims that this functor is not invocable, which is definitely wrong.
Am I missing something or it is a defect in the standard? If this behavior is correct, then what is the point in std::invoke and all its friends? What I mean is that simple function objects can be easily called without any facilities, but I though the main purpose of std::invoke is to generalize and simplify working with all callables, including the tricky ones, like pointers to members. The fact that std::invoke cannot invoke a clearly invocable target seems weird to me.
The problem is that functor is not a function, but a data member. As such, &MyClass::functor is not a pointer to member function, but a pointer to member data. This distinction means that you cannot pass any other arguments to std::invoke, as you cannot call a data member; but for some data members, like your functor you can. The standard is not clear on this before C++11, and so there was LWG issue 1520 which got merged in C++11.
I mean you can rewrite your example as:
std::invoke(&MyClass::functor, mc)(110);
// or for maximum confusion
std::invoke(std::invoke(&MyClass::functor, mc), 110);
but I don't think that's what you want. Thanks to Barry, this is a bad idea, as what would the following code do:
struct X {
std::function<void()> f;
};
std::invoke(&X::f, x); // gets f, or calls f?
Getting f would make it consistent with other data members, but then you have no way of invoking f if f takes no arguments. Calling f means that you get an inconsistency with other data members when you just want to get them.
In c++ standard library almost all algo function takes a callable object as a argument. Now I want to try this thing with my program. I opened the the headers for function like find_if or search_n() but could not understand much about how these callable object parameters are handled and off course how argument is passed to them especially for lambda object ( can bind() be used for lambdas, I dont know)
Can any one explain me how this thing works. Thanks in advance
Just have a template parameter for the function-like type and take an argument of that type:
template <typename Function>
void foo(Function func) {
// Use func like so
func(10);
}
This is how the standard library algorithms do it. You could call it with a lambda like so:
foo([](int x) { std::cout << (x * 2) << std::endl; });
Of course, this requires that you specify in your documentation what kind of function you expect as the Function type (until we get (until we get Concepts). Should it be unary? Binary? What type arguments should it take? What should it return?
Alternatively, you can take a function of a specific type by using std::function:
int foo(std::function<int(char)> func) {
return func('a');
}
This time, foo will only take function-like objects that take a char argument and return an int. There is one downside to this method, however, which is that the compiler is unlikely to inline any lambdas you pass as func.
The most basic way to take a function as an argument is with a function pointer:
int foo(int (*func)(char)) {
return func('a');
}
However, this will only take function pointers (some lambdas can be converted to function pointers). It won't take functors or anything else of the sort.
All algorithm function must get some functions to test the algo like find_if have to know which predicate you want to test on the loop. All std lib works with template and you can pass your function test as callable object. Callable object are object that have overload operator(), with it, std lib will call your sent object with some parameter and get up a return value if necessary. You can find which parameters and return values that are needed on some site, specialy I always use http://www.cplusplus.com/ you can find many documentation on all std lib in reference menu.
Special exemple from you :
http://www.cplusplus.com/reference/algorithm/find_if/
find_if will take 2 iterators, one as first and an other as last, and a callable object that will take a object pointed by your iterator and return a bool.
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.