I tried to use for_each with boost::trim. In the first place I used a wrong code
std::for_each(v.begin(),v.end(),&boost::trim<std::string>));
// error: too few arguments to function
then I fixed (reading online) with this
std::for_each(v.begin(),v.end()
,boost::bind(&boost::trim<std::string>,_1,std::locale()));
How the compiler works when it needs to pass this function to for_each. I thought that since std::locale is the default parameter for the second input argument of boost::trim my code should have worked.
Default arguments are applied when you call a function, but they don't form part of the function signature. In particular, when you call a function through a function pointer, you have generally lost the information which default arguments are available:
void (*f)(int, int);
void foo(int a, int b = 20);
void bar(int a = 10, int = -8);
f = rand() % 2 == 0 ? foo : bar;
f(); // ?
The upshot is that to use bind on f you will always need to populate both parameters.
You can always write it using a lambda:
std::for_each(v.begin(), v.end(), [](std::string & s) { boost::trim(s); });
Now compiler will have enough knowledge to use default parameters.
Related
Let's say you have a function like this:
int Function(int a = 5, int b = 10){
...
}
When you call the same function with fewer parameters then it should have, for example:
int var = Function(8);
'a' becomes 8, and 'b' gets the default value 10;
With this in mind, let's say I have another function called Function3 that receives another function as its argument:
int Function3(int x, int Function2 (int)){
...
int m = Function2(x);
...
return m;
}
How do I set the default function (function2) that should be called if I do not send any function as an argument to Function3 (using the lambda functions)?
So if I do this:
int ver = Function3(y);
instead of this:
int ver = Function3(y,std::sin)
How do I tell it to, for example, multiply the number with 3 if nothing has been sent as a third argument? (and if it has to use that function to work with x and y).
Your parameter should be a pointer to a function, and you can assign this like any other parameter.
int Function3(int a, int b, int (*func)(int,int) = Function2)
{
func(a,b); //call will use passed function, or Function2 if one wasn't provided
}
The way I do this is that I make the default value be NULL, and then in the implementation of the function I begin with an if statement which checks whether NULL was passed for that parameter, and if so, uses the intended default instead.
I'm trying to understand bind and pre-fill functions in C++.
Here's my example:
#include <iostream>
#include <functional>
#include <vector>
class Voice
{
public:
double mValue;
private:
};
class VoiceManager
{
public:
VoiceManager() { }
~VoiceManager() { }
typedef std::function<void(Voice &)> VoiceChangerFunction;
inline void UpdateVoices(VoiceChangerFunction callback) {
for (int i = 0; i < mNumOfVoices; i++) {
callback(mVoices[i]);
}
}
static void SetValue(Voice &voice, unsigned int value) {
voice.mValue = value;
std::cout << voice.mValue << std::endl;
}
private:
static const int mNumOfVoices = 4;
Voice mVoices[mNumOfVoices];
};
int main()
{
VoiceManager voiceManager;
VoiceManager::VoiceChangerFunction callback;
callback = std::bind(&VoiceManager::SetValue, std::placeholders::_1, 100);
voiceManager.UpdateVoices(callback);
}
Basically, I create a VoiceChangerFunction function (object) that takes a Voice & as first parameter and returns void.
Later, I bind a function that will take as first parameter the one I'll give to it when I call it, and another parameter that I give when I bind it (100, in my example).
Right?
What I don't understand is: then, this function is passed to UpdateVoices(), which take as input a function/object that has 1 param (Voice &), not 2 as created in my bind function (Voice &, unsigned int).
How can it works?
Its like to have void VoiceChangerFunction(Voice &voice) and call VoiceChangerFunction(Voice &voice, unsigned int value ).
The function prototype is different. I mean: the callback bind I created isn't a VoiceChangerFunctions function, because it takes more parameters.
How can it works/match?
That is exactly the beauty of bind and std::function at works. You are defining the callback as function taking one argument, and bind is returning a function object which takes one argument.
The main point here is that it actually calls the function which takes 2 parameters, but the second one is fixed, and will always be 100 (in your case). This is the sole purpose of binders - to provide a way to call functions with different set of arguments with some fixed values. If you would be calling the function taking the same set of arguments, there would be no reason to use binders at all!
Knowing that bind is similar to lambdas, the same code could be written as - and probably be more clear:
VoiceManager::VoiceChangerFunction callback;
callback = [](Voice& v) { VoiceManager::SetValue(v, 100); };
voiceManager.UpdateVoices(callback);
And if you are curious how it works, you might try to create a binder framework yourself. If you are only doing it for educational purposes and not worried about too many details, it is not that hard.
When you bind, you're making a new function that only takes Voice as a param, that's why it works.
void a_func(int x) { return; }
std::function<void(void)> new_func = std::bind(&a_func, 1);
new_func now has the signature of void(void), so you could pass it around to anywhere that expects a function of type void(void).
When you call new_func, it really calls a_func(1).
Your assumption about bind is wrong.
Your bind call returns a function object that will accept one parameter, namely the placeholder. The other parameter on your function is already bound to 100.
A little example:
void foo(int i1, int i2) {};
std::function<void(int,int)> fn1 = std::bind(foo, std::placeholders::_1, std::placeholders::_2);
std::function<void(int)> fn1 = std::bind(foo, std::placeholders::_1, 1);
std::function<void()> fn1 = std::bind(foo, 1, 1);
The bind will create a matching function depending on bound and unbound parameters.
Update
The compiler will generate a struct from the bind expression and a copy of your parameter. Simplified something like this(this will not compile):
struct Function_{
void(*fn)(Voice &, unsigned int)
unsigned int i_;
Function_(void(*f)(Voice &, unsigned int), unsigned int i):fn(f),i_(i){}
void operator()(Voice& v){
fn(v, i_);
}
}
fn is the first parameter which is a function pointer and the bound (100) is the second. Then all you need is some type erasure and your own bind is ready to go.
I remember vaguely that python allowed something like
def foo( x ):
....
f = foo( 5 )
Is something like that possible in c++ so that if I have a member function
class C {
void foo( int x ) { ... }
so that I can define a pointer or variable that would effectively point at foo( 5 )
The reason why I want to do this is because I have many listeners that I need to subscribe to a callback and keep information who gets called
class C {
map<int, ptrSender> m_sender;
void subscribe() {
for (const auto& p : m_sender) {
p .second->register( Callback( this, &C::onCall ) )
}
My problem is that the onCall does not return which sender called back, but I would need this information. So, instead of doing something like this
void subscribe() {
m_sender[0]->register( Callback( this, onCall_0 ) );
m_sender[1]->register( Callback( this, onCall_1 ) );
....
void onCall( int sender_id ) { ... }
void onCall_0() { onCall( 0 ); }
void onCall_1() { onCall( 1 ); }
....
I was hoping I could pass something into register that would return a call with a preset argument. Is this possible?
EDIT: I am trying to use a lambda function, but I am running into the following problems
auto setCall= [this]( int v ) { &C::onCall( v ); }
gives the compile error
lvalue required as unary&opeand
This
auto setCall= [this]( int v ) { C::onCall( v ); }
....
p.second->register( Callback( this, &setCall( p.first) ) ); /// <__ error now here
complains again, now in the second line
lvalue required as unary&operand
and this
auto setCall= [this]( int v ) { C::onCall( v ); }
....
p.second->register( Callback( this, setCall( p.first) ) ); /// <__ error now here
complains about invalid use of void expression, but I assume I have to pass in a reference to make the register function happy
Callback seems to be defined as
# define CallBack(obj,func) ProfiledBasicCallBack(obj,fastdelegate::FastDelegate0<void>(obj,func),#func)
Yes, you can use std::bind. Example usage: http://ideone.com/akoWbA.
void foo( int x ) { cout << x << endl; }
auto x = std::bind(foo, 5);
x();
However, with modern C++, you should use a lambda. Like so:
void foo( int x ) { cout << x << endl; }
auto x = []() { foo(5); };
x();
Note that this foo function is outside of the class C in this example. If you wish to contain it inside, then with std::bind you need to pass the instance of the object you wish to call on, e.g.
C c;
auto x = std::bind(&C::foo, &c, 5);
x();
or with lambdas:
C c;
auto x = [&c]() { c.foo(5); };
x();
What you are looking for is std::bind(). It takes one callable object, and gives you another callable object with predefined values for its parameter, and maybe some optional parameters forwarded to it.
A word of warning: this is a fairly steep learning curve. You need to understand templates.
If you want to bind a parameter value to a compile-time constant argument (like 5 in your example), then the problem can be solved by introducing a simple wrapper function that will call your function while passing the desired constant values as corresponding arguments.
But when the argument is a run-time value, then the answer is no: it is generally not possible to create a credible implementation of such function pointer binding in C++ (unless you are using some compiler-specific extension).
However, in C++ you have a variety of alternative tools at your disposal. You can create a function object that will mimic the functionality you desire. Such function object can be created by using std::bind, by using lambda-expressions, or even implemented manually.
The resultant function object will be "callable" and will behave similarly to function pointer at superficial level, but nevertheless it won't be a function pointer, won't be convertible to a function pointer and won't be accepted where a genuine function pointer is required. In other words, if your register method is declared to expect a function pointer as its second argument, then there's nothing you can do here. Neither std::bind, nor lambdas, nor anything else in the language will help you to achieve this kind of parameter binding.
For this reason it is generally a good idea to steer clear of function pointers in such designs and implement such functionality in terms of generic callable objects. The simplest thing to use might be std::function objects in place of raw function pointers.
I have a function that requires a function pointer as argument:
int func(int a, int (*b)(int, int))
{
return b(a,1);
}
Now I want to use a certain function that has three arguments in this function:
int c(int, int, int)
{
// ...
}
How can I bind the first argument of c so that I'm able to do:
int i = func(10, c_bound);
I've been looking at std::bind1st but I cannot seem to figure it out. It doesn't return a function pointer right? I have full freedom to adapt func so any changes of approach are possible. Althoug I would like for the user of my code to be able to define their own c...
note that the above is a ferocious simplification of the actual functions I'm using.
The project sadly requires C++98.
You can't do that. You would have to modify func to take a function-object first. Something like:
int func( int a, std::function< int(int, int) > b )
{
return b( a, rand() );
}
In fact, there is no need for b to be an std::function, it could be templated instead:
template< typename T >
int func( int a, T b )
{
return b( a, rand() );
}
but I would stick with the std::function version for clarity and somewhat less convoluted compiler output on errors.
Then you would be able to do something like:
int i = func( 10, std::bind( &c, _1, _2, some-value ) );
Note all this is C++11, but you can do it in C++03 using Boost.
Well, if you know at compile time, what you have to bind c with, you could define a new function
int c_bound(int a, int b) {
return c(a,b,some_value);
}
That's obviously not a generic solution but might solve your current problem. Otherwise K-ballo's solution seems to be the only easy generic one. However, that requires you to be able to change the signature of func. If you really have an API that you can't touch the signature, and you still need to bind an argument AND if the above solution doesn't solve your specific case: (Caution, overkill ahead) I've always wanted to use an LLVM based solution to compile a function at runtime and pass its address in such situations.
You would be unable to use a 3 argument function as a 2 argument function; Mainly because there is no real way to determine what the 3rd parameter would do.
While the above answer would work, here is another option:
If one of the parameters for c(), in use within func, is constant, you could write a wrapper function for c(int, int, int):
int d(int a, int b)
{
return c(a, b, 0); //use a constant parameter
}
or, if you can determine the 3rd parameter from the two given parameters, you can also try:
int e(int a, int b)
{
int extra = 0;
///Determine extra from a, and b
return c(a, b, c);
}
I'm new to this and now sure whether this is doable. I want to add a argument of std::set<std::string> to a function, and set its default value to be NULL, to avoid impact on previous uses.
So basically,
func(int a); turns into
func(int a, std::set<std::string> & temp = NULL);
but this will give me an error "error C2440: 'default argument' : cannot convert from 'int' to 'std::set<_Kty> &'"
Can anybody help me on this?
Thanks
In order to set the default to NULL, you'd have to be passing an std::set<std::string>*, not a reference to a value type.
Furthermore, if you are passing a non-pointer type and you want to assign any default value at all, it has to be a const reference, because you can't (advisably!) assign a temporary to it otherwise.
So your choices for "default" values are basically:
std::set<std::string>* = NULL
or:
const std::set<std::string>& = std::set<std::string>()
or option 3, using function overloading more directly:
void myfunction() {dothing(0);}
void myfunction(std::set<std::string>& optional_param)
{ dothing(optional_param.size()); }
or option 4, having a corresponding bool indicating whether parameter is "set":
void myfunction(std::set<std::string>& param, bool param_has_meaning=true) {}
It looks like you're already on the track to the third option. You just need to write two definitions, one with and one without the parameter.
You have the right idea - using a reference. However, a reference cannot be NULL by default, like a pointer can. Therefore, what you probably want to do is overload the function so that you use void func(int a) when you don't want to pass a set as a parameter and use void func( int a, std::set<std::string>& temp)
This way, you can actually provide two separate implementations - one that works on a set and one that doesn't. From a usage point of view, it would have the same effect as a default parameter. From a coding point of view, each implementation would have a clearer purpose.
If you're not going to be modifying the set, might I suggest using a const reference instead:
void func( int a, const std::set<std::string>& temp )
You can't have a NULL reference in C++.
The simplest way would be to have a dummy empty set:
std::set<std::string> empty;
void func(int a, std::set<std::string>& temp = empty)
{
// ...
}
You can then call:
func(1);
Neater, still, would be to use function overloading to create a wrapper so that you have no need to default:
void func(int a, std::set<std::string>& temp)
{
}
void func(int a)
{
std::set<std::string> empty;
func(a, empty);
}
// And then...
func(1);
All this assumes that if you pass in a set you're going to modify it somehow. It's not clear from your question what your intention is but I've made the assumption on the basis that your reference is non-const. If I've miscalculated, then the answer is even simpler:
void func(int a, const std::set<std::string>& temp = std::set<std::string>())
{
}
The following will give you an empty set object:
std::set<std::string>()