Binding member functions - c++

In the example in member function section: Member functions
We got a struct X:
struct X {
int foo(int);
};
Preferred syntax
boost::function<int (X*, int)> f;
f = &X::foo;
X x;
f(&x, 5);
Portable syntax
boost::function2<int, X*, int> f;
f = &X::foo;
X x;
f(&x, 5);
My questions are:
Why do I have to put an additional X* argument when my int foo(int) only take one argument? Also, is that the same as using boost::bind, such as:
Person *person = new Person("Tu", 23);
boost::function newFunc2 = boost::bind(&Person::printInfo,person);
What's the difference between prefer syntax and portable syntax and when to use one over another?
What is function object? Is that function pointer?

Any member function has a pointer to the object to operate on implicitly set as its first parameter. When you have code like this: X x; x.foo(10); the compiler might really be calling foo(&x, 10) for you (see here for two ways this may be handled) - obviously, the name foo would have been mangled in some way.
See the Boost documentation for a description of the syntaxes. Below is the most relevant extract from the page. Basically, you should use the preferred version if your compiler supports it, as its closest to the normal definition for a function pointer (readability) and uses fewer template arguments (faster compile times).
Boost.Function has two syntactical forms: the preferred form and the portable form. The preferred form fits more closely with the C++ language and reduces the number of separate template parameters that need to be considered, often improving readability; however, the preferred form is not supported on all platforms due to compiler bugs. The compatible form will work on all compilers supported by Boost.Function. Consult the table below to determine which syntactic form to use for your compiler.
A function pointer is a plain old pointer that happens to accept functions with a specific return type and argument list. A function object is any type that has an operator() defined - allowing it to be called as a function.

You need to pass object of type X, because that is a member function pointer. You need an object on which you are calling that member function.
portable syntax is for older and newer compilers, and prefered syntax can not compile on older compilers. The detail difference is explained at the functor tutorial page
function object is such object which you can call as a function. It can be function pointer or member function pointer

Related

where auto keyword can't determine the type in C++

Auto keyword is used to infer the type of the variable based on the initialization. But I read on internet that auto can't determine the type of the function parameters. I didn't understand the reason why auto can't determine the type when used with function parameters. Can any one please let me know why auto can't be used with function parameters and any other cases where auto keyword can't be used to determine the type.
"Can't" is a strong word. After all, lambda parameters can use auto (in C++14). It's not so much "can't" as "doesn't". And perhaps "won't".
The question ultimately comes down to this: what does this actually do?
void foo(auto x)
{
std::cout << x << std::endl;
}
auto deduction is ultimately based on providing an initializing expression, which is used to deduce the actual type. This declaration contains no initializing expression.
C++ is a statically typed language; that means the compiler must be able to determine the type of every expression and object at compile time. From just the above, the compiler can deduce nothing.
So how can the compiler know that std::cout << x is legal C++ syntax? It can only tell that if there is an operator<< overload that takes std::cout and x. It can't figure out what is being called without first knowing the type of x. Which it doesn't; it can be different for different invocations of the function.
However, there is one C++ construct where the above makes sense: a template. This is exactly what using auto in lambda parameters does; it implicitly transforms the function into a template function. So [](auto x) {return x;} effectively becomes an operator something like this:
template<typename T>
auto operator()(T x) {return x;}
However, this conversion doesn't just fall out of having auto as a deduction syntax. It has to be something the standard is explicitly written to require. And, with the exception of C++14 generic lambdas, it doesn't.
Concepts TS includes this facility. However, this is merely an extension of the ability to use concepts in function parameter lists at all. That is, they already have a way to make a function implicitly create a template function, so they just added auto as essentially a case of "a concept that accepts any type".
But this was explicitly excluded from the C++20 version of concepts. The general reason for this exclusion is that, up until this point, template functions could be detected because they always had to have some special syntax. Namely, the inducer template<args>. With the Concepts TS version, there is concern that people will write template functions without realizing it.
And template functions behave differently from non-template functions. A template function is a family of functions, so you can't get a pointer to the family itself. You'd have to explicitly instantiate the template to get a pointer to that particular function.

why can't apply mem_fn to member function of std::string?

struct int_holder {
int value;
int triple() {return value*3;}
};
int main(int argc, const char * argv[])
{
std::string abc{"abc"};
int_holder one{1};
auto f1 = mem_fn(&std::string::clear);
auto f2 = mem_fn(&int_holder::triple);
f1(abc);
f2(one);
}
i test such code in Xcode and the compiler issues such error
it seems mem_fn is fine with member functions of user-defined class but not with member functions of standard string, what's the different, and why?
thanks for your reading, help me plz!
I can reproduce this with Clang 3.1-3.3 as well as 3.6. Looks like bug 16478.
Simplest fix is to just use a lambda or equivalent. Other completely non-portable workarounds include either disabling extern templates with
#ifndef _LIBCPP_EXTERN_TEMPLATE
#define _LIBCPP_EXTERN_TEMPLATE(...)
#endif
before you include any headers (in essence applying r189610); and doing an explicit instantiation of either the member function (template void std::string::clear();) or the entire class.
That said, you should not take the address of a member function of a standard library class. [member.functions]/p2:
An implementation may declare additional non-virtual member function
signatures within a class:
by adding arguments with default values to a member function signature;187
by replacing a member function signature with default values by two or more member function signatures with equivalent behavior; and
by adding a member function signature for a member function name.
187) Hence, the address of a member function of a class in
the C++ standard library has an unspecified type.
As for the standard, you can't take a pointer to any standard nonstatic member because the library implementation is allowed to add hidden overloads, defaulted function template parameters, SFINAE in the return type, etc.
In other words, & std::string::clear is simply not a supported operation.
In terms of Clang, it looks like an issue with hidden symbol visibility. Each shared object (linker output) file gets its own copy of certain functions to avoid the appearance that third-party shared libraries implement the standard library. With different copies floating around, the equality operator over PTMFs would not work: If you retain the value & std::string::clear from an inline function, it might not compare equal to itself later. However, it's probably a bug, since std::string should be completely implemented by the libc++.so shared library. Only other specializations of std::basic_string could really justify this behavior.
A good fix would be to use a lambda instead. []( std::string & o ) { o.clear(); } is a superior alternative to mem_fn. It avoids the indirect call and its sizeof is smaller. Really, you shouldn't use mem_fn unless absolutely necessary.

Overload by return type and arguments

Is valid to have
int func();
float func(int x);
I know isn't possible overloading without templates by return type only, but this is valid correct?
Yes it is. The rule for overloading is that the parameters need to be of different type and/or number; when this is satisfied, the return type can be different for the various overloads. Given the actual arguments, the compiler can determine which overload to call.
Only overloading by return type is invalid, because the compiler cannot make a choice based on the return value; suppose you have overloads int f() and float f(), and you do
(void)f();
In this situation, there's no telling which f you intended to call. (Unless there would be some arbitrary preference for types specified in the Standard, but there isn't, and it would be hard to come up with a sensible one.)
Functions are identified by their signature.
in C++ function signature include,
name
argument type
no of arguments
order of argument
Return type of function is not consider as a part of signature.
When a function call is encountered in a program then the compiler will look for functions with that name. If multiple functions have same name(function overloading). then the compiler will check the above signature. if an exact match is not found then compiler will do some conversions and check for a match. Still not found a match it will show an error
Yes, it is correct. A function is defined by
the namespace
the name of the function
the types of arguments
But, the return type is not taken into account.
See this example :
int f(); // correct
double f(int x); // correct
void f(double y); // correct, the type is different
char f(int z); // Not correct, same signature than the 2nd function
You already got a few answer stating that it is possible, but a different question is whether it is desirable, and at this point I would advice against it in your case as it puts a burden on the user: they need to figure out what overload is picked to know what the function returns.
Note that this is not a statement that in general it is not desirable, there are many cases where having different return types for different functions make sense, for example sqrt taking a float will return a float, and if the input is a double it will produce a double, but it is natural from the syntax and the call what the return type is.
In the artificial example you provided that is not the case, or at least it is not obvious, so I'd recommend not to overload but produce different named functions.
Yes this is fine as you have different arguments for two overloads.Just for your information why compiler can't deduce from only return types which overload to call.
There's a concept called name mangling. Compiler mangles name of each function as per it's ease to call that appropriately.So if a function is,
int foo (int x );
mangled name would be something in line with foo_int. In this return type is not taken into account. So if I have two overloads like
int foo (int x );
int foo (char x);
mangled names would be something
foo_int
foo_char
respectively. But if you only choose return type for your overload resolution then it will fail as return type is not taken into account in name mangling.

Points to member variables and templating

I am currently using a templated function to evaluate the derivatives of mathematical functions, like so
template <class func_type>
arma::mat matrixDerivative
(func_type func, const double x, double h, double b=1.4) {
// <implementation details>
}
The template parameter allows me to use either function pointers or functors to evaluate the right-hand side.
Is there an easy way to extend this to evaluate the derivatives of functions that are class methods? I wasn't able to wrap my head around the use of function pointers to member functions and I couldn't work out the details of having a functor as a class attribute that still had access to its parent's attributes and methods.
My questions usually aren't clear, so feel free to ask for clarifications in the comments before answering.
In C++11 simply use a lambda:
[&]( double x )->double {
return ptr->method(x);
}
which generates a function object that can be invoked with double. The above construct assumes that the lambda will be used and discarded before the end of the current scope ([&] is unsafe otherwise).
Note that ->double can be omitted for single-line and void returning lambdas in C++11, and omitted even on multi-line lambdas in C++1y if you are ok with the return type it deduces (based off the first return statement in your function).
In C++03, std::mem_fun can be used, or you can create a custom function object.
In C++1y:
[&](auto&&... x) {
return ptr->method(std::forward<decltype(x)>(x)...);/
}
creates a perfect-forwarding functor wrapper. I would rarely do that kind of thing, even in C++1y, outside of seriously industrial library code. Less verbose we get:
[&](auto&&... x) {
return ptr->method(x...);
}
which lets us imperfectly forward, and defer selection of the overload to the point of use of the lambda, not the point where the lambda was written, which can be nice. (if any of the methods use rvalue or by-value calls, going back to perfect forwarding becomes tempting)
In C++11, std::mem_fn requires that the method in question not be overloaded, or that the overload be manually resolved (with an arcane-looking cast). std::bind then wraps that with a perfect-forwarding function object. The main advantage this procedure is is that the type of the construct, while implementation defined, can be determined, so you can have a function that returns the type in question. However, that is a pretty esoteric advantage: I would go with the lambda.
Lambdas, while strange, are increasingly common in C++, and are easier to understand what they are doing than a chain bind mem_fun expression in my experience as they look more like "normal" code (after you get over the "magic").

std::bind and std::function questions

int func(int x){return x;}
...
std::function<int(int)> x = std::bind(func, std::placeholders::_1);
x(123);
Does x(123) actually call the operator() of the functor which std::function generated which in turn calls the operator() of the functor which std::bind generated which finally calls func? Does this get optimized into something as optimal as calling func(123)?
Where does the functor live which std::bind generates? In what scope? And how does std::bind name it? (can there be name collisions)
Can lambdas replace all uses of std::bind?
Is std::bind as optimal as implementing it as a lambda instead?
What's up with the syntax of the template argument of std::function? How does that get parsed and how can I use that template argument syntax elsewhere?
Does x(123) actually call the operator() of the functor which std::function generated which in turn calls the operator() of the functor which std::bind generated which finally calls func? Does this get optimized into something as optimal as calling func(123)?
I wouldn't describe the operator() of std::function as 'generated' (it's a regular member), but otherwise that is a good description. Optimizations are up to your compiler, but be warned that to optimize the indirection of std::function (which requires the use of type erasure) a compiler may need to perform heroics.
Where does the functor live which std::bind generates? In what scope? And how does std::bind name it? (can there be name collisions)
The call to std::bind returns a functor of unspecified type, and a copy of that functor is stored inside the x object. This copy will live as long as x itself. There is no name involved so I'm not sure what you mean by that.
Can lambdas replace all uses of std::bind?
No. Consider auto bound = std::bind(functor, _1); where functor is a type with an overloaded operator(), let's say on long and int. Then bound(0L) doesn't have the same effect as bound(0) and you can't replicate that with a lambda.
Is std::bind as optimal as implementing it as a lambda instead?
This is up to the compiler. Measure yourself.
What's up with the syntax of the template argument of std::function? How does that get parsed and how can I use that template argument syntax elsewhere?
It's a function type. Perhaps you're already familiar with the syntax for pointers/references to functions: void(*)(), int(&)(double). Then just remove the pointer/reference out of the type, and you just have a function type: void(), int(double). You can use those like so:
typedef int* function_type(long);
function_type* p; // pointer to function
1 . Does x(123) actually call the operator() of the functor which std::function generated which in turn calls the operator() of the functor which std::bind generated which finally calls func? Does this get optimized into something as optimal as calling func(123)?
If you have optimizations enabled, the 'stuff' gets inlined and you can count on this being as optimal as calling func(123).
2 . Where does the functor live which std::bind generates? In what scope? And how does std::bind name it? (can there be name collisions)
Precising: bind generates a 'fleeting', implementation defined, bind expression, that is assignable to function<>. Function is just a class template (Thanks, Luc T.). And it lives in the standard library. However, the bind expressions are implementation defined.
The standard library does come with traits (std::is_bind_expression<>) to allow MPL detection of such expressions. One decisive feature of bind expressions over std::function is that they are (what I'd call) deferred callable objects (i.e. that they retain full call site semantics including the ability to select overloads at the actual application site). std::function<>, on the other hand, commits to a single prototype and internally stores the callable object by type erasure (think variant or any).
3 . Can lambdas replace all uses of std::bind?
4 . Is std::bind as optimal as implementing it as a lambda instead?
AFAICT lambdas should compile down to about the same as the bind expressions. One thing that I think lambdas can't do that bind expressions can is nested bind expressions
Edit While the specific idiom of nested bind expressions is not replicatable using lambdas, lambdas are of course able to express (nearly) the same much more naturally:
bind(f, bind(g, _1))(x);
// vs.
[](int x) { f(g(x)); };
5 . What's up with the syntax of the template argument of std::function? How does that get parsed and how can I use that template argument syntax elsewhere?
It is just a function signature (the type of a function), being passed as template parameter.
You can also use it as a function parameter type, which degrades to a function pointer(similar to how array by-value parameters degrade to pointers, Thanks David!).
In practice, most anywhere, as long as you don't have a need to name a variable/type:
void receiveFunction(void(int, double)); // spunky 'function<>'-style syntax
void sample(int, double) { }
int main()
{
receiveFunction(sample);
}
void receiveFunction(void (*f)(int, double)) // boring 'old' style syntax
// void ( f)(int, double) // ... also ok
{
// ..
}
Can lambdas replace all uses of std::bind?
C++14 will allow lambdas to mostly replace bind. Responding in particular to Luc Danton's answer, in C++14, you can write templated lambdas using auto such that bound(0) and bound(0L) behave differently.