I'd like to reduce amount of syntax required to refer to a function and was wondering if there was a way to do something like:
(NOT COMPILABLE)
using pushToLastUsed = mSomeLongStackFIFOObject.push_back;
// or
auto pushToLastUsed = mSomeLongStackFIFOObject.push_back;
then I could to something like:
pushToLastUsed(10);
instead of:
mSomeLongStackFIFOObject.push_back(10);
Of course I could make a macro like:
#define pushToLastUsed mSomeLongStackFIFOObject.push_back
// some code using it here
#undef pushToLastUsed
but I'd prefer not to use macros.
One solution might be to use a lambda expression to capture the function call into a callable object :
#include <vector>
void foo(std::vector<int> & bar)
{
auto pushToLastUsed = [&bar](int index) {
bar.push_back(index);
};
pushToLastUsed(10);
}
Though in my opinion there is very little to gain from doing this, even if you replace bar with a very long identifier.
My first idea was something along the line of the other answer. On a second read of your question I understand that it is mainly the long name of the object that you want to avoid to repeat. Hiding a call to a standard function should be done with care as its main effect is to obfuscate your code. Everybody knows what push_back does, but even you will likely forget what exactly pushToLastUse does. A different option is to alias only the mSomeLongStackFIFOObject with a shorter name as in
auto& short_name = mSomeLongStackFIFIObject;
short_name.push_back(10);
When you're writing mSomeLongStackFIFOObject.push_back(10); you're actually calling SomeLongStackFIFOClass::push_back(&mSomeLongStackFIFOObject, 10);
One option is to do:
auto& m= mSomeLongStackFIFOObject;
And then:
m.push_back(10);
It will shorten it and still let you use any variable you like.
If the variable is global, you can always do:
static inline void pushBack(int n) { mSomeLongStackFIFOObject.push_back(n); }
If you're trying to shorten the access, I can guess that you're using the variable more than once; then it could make sense to try to put all the accesses in a function that belongs to the class.
You can achieve the desired behaviour by binding the object mSomeLongStackFIFOObject to the member function push_back and using a placeholder for its argument. This requires at least a C++11 compiler.
Consider the following example:
#include <functional>
#include <iostream>
struct A {
void push_back(const int& n) { std::cout << "push_back(" << n << ")\n"; }
};
int main() {
A mSomeLongStackFIFOObject;
std::function<void(const int&)> pushToLastUsed = std::bind(
&A::push_back,
&mSomeLongStackFIFOObject,
std::placeholders::_1
);
pushToLastUsed(10); // push_back(10)
}
Some notes about this:
As Mirko already mentioned correctly, calling a non-static member function is basically the same as calling a static member function with this as implicit first parameter. The binding of an instance of struct A as first parameter makes use of this fact.
Type inference using auto does work for member functions without any parameters but not in the case above.
If the non-static member function is overloaded (e.g. std::vector<T>::push_back) you have to explicitly state the template parameters for the function template std::bind. See Using std::tr1::bind with std::vector::push_back
or Are there boost::bind issues with VS2010? for further information.
Related
I'd like to be able to bind a function with set parameters within itself - I've been given an implementation of scheduled callbacks wherein there's a multimap from std::chrono time signatures to std::function<void(void)>, and I want to have this method do some stuff and then schedule to call itself again in the future. Thus, creating a std::bind of itself to ultimately get into this multimap with an associated time.
I'm having a devil of a time actually trying to get the syntax right here, and I'm not really able to parse the error messages / see why things aren't working. For example,
#include <functional>
#include <iostream>
class x {
public:
void testBind(char y);
};
void x::testBind(char y) {
std::cout<<"Blah! " << y << "\n";
auto boundItself = std::bind(&x::testBind, &x, std::placeholders::_1);
boundItself('h');
}
produces the following error on the line with std::bind:
error C2275: 'x': expected an expression instead of a type
https://godbolt.org/z/rncfchvPb
As a toy example, I should be able to get recursive printouts of Blah etc., but the syntax around Bind aren't being cooperative.
https://en.cppreference.com/w/cpp/utility/functional/bind
From the std::bind documentation, here's an example that DOES work:
struct Foo {
void print_sum(int n1, int n2)
{
std::cout << n1+n2 << '\n';
}
int data = 10;
};
int main()
{
using namespace std::placeholders;
Foo foo;
auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
f3(5);
return 0;
}
Now, I notice that in this example, there's first &Foo:print_sum, e.g. capital F, e.g. the class definition, while the second argument is &foo, a lowercase, e.g. a specific instance of the class. But how do I get this argument into my bind definition? Do I need to declare a static global instance of my class to use as a sort of placeholder here?
You came close by noticing that the second parameter had to be a specific instance of the class. This is an application to std::bind of a more general principle – every call to a non-static member function must be associated with an object of the class. In std::bind, this principle takes the form of providing the object as the second parameter. In more common cases, this principle takes the form of providing an object in front of the function call, as in obj.testBind('h'), where obj had been earlier declared as x obj;.
So the question is which object should be associated with the bind? Since the context is inside a member function, one likely possibility is the object associated with that call. Remember, every call to testBind() must be associated with an x object. This applies to the call you hope to make in the future (via the bind) and to the call that is currently executing. Since the goal is to repeat the current call, it makes sense to use the current object.
The name given to the address of the current object is this, so the bind you are looking for is probably
std::bind(&x::testBind, this, std::placeholders::_1)
// ^^^^
Alternatively, you could abandon std::bind and use a lambda.
auto boundItself = [this](char yy) { testBind(yy); };
Wait a minute! Where is the object for the call to testBind() in the lambda version? What happened to the principle driving this answer? (If you were already asking that before reading this far, good observation skills.)
Nothing happened to the principle. We have simply stumbled into a different context. Inside a member function, there is a shorthand syntax that obscures the principle. Accessing members of the current object is so common that the compiler will assume the current object if none is specified. This assumption spills into lambdas that capture this. The statement testBind(yy); in the lambda is merely shorthand for this->testBind(yy);. There is still an object associated with the new call to testBind().
A constructor from a class I'm inheriting requires a non-trivial object to be passed in. Similar to this:
MyFoo::MyFoo() : SomeBase( complexstuff )
{
return;
}
The complexstuff has little to do with MyFoo, so I didn't want to have to pass it in.
Instead of writing some kind of 1-off temporary function that returns complexstuff I used a lambda. What took me a few minutes to figure out is I have to invoke the lambda. So my code now looks like this:
MyFoo::MyFoo() : SomeBase(
[]()
{
/* blah blah do stuff with complexstuff */
return complexstuff;
} () )
{
return;
}
If you didn't catch it, it is subtle. But after the lambda body, I had to put () to tell the compiler to immediately "run" the lambda. Which made sense after I figured out what I had done wrong. Otherwise, without the () to invoke the lambda, gcc says something similar to this:
error: no matching function for call to 'SomeBase(<lambda()>)'
But now that has me thinking -- did I do this correctly? Is there a better way in C++11 or C++14 to tell the compiler that I want it to immediately invoke a lambda I've written? Or is appending an empty () like I did the usual way to do this?
But now that has me thinking -- did I do this correctly?
Yes you did.
Is there a better way in C++11 or C++14 to tell the compiler that I want it to immediately invoke a lambda I've written?
Not that I know of. A lambda is also just a function object, so you need to have a () to call it, there is no way around it (except of course some function that invokes the lambda like std::invoke).
If you want you can drop the () after the capture list, because your lambda doesn't take any parameters.
Or is appending an empty () like I did the usual way to do this?
Yes, it is the shortest way. As said before, std::invoke would also work instead, but it requires more typing. I would say a direct call with () is the usual way it is done.
In C++17 you can use std::invoke. This does the exact same thing as you did, but perhaps you will find this clearer.
#include <iostream>
#include <functional>
void foo(int i)
{
std::cout << i << '\n';
}
int main()
{
foo( std::invoke( []() { return 1; } ) );
}
There's no way to tell the compiler to invoke the lambda immediately. The simplest course (both in terms of complexity and number of typed characters) is what you did already. It's also very idiomatic for anyone who has worked with languages that have closures (I'm thinking JavaScript here).
If you want to avoid the syntax, then either modify SomeBase or complexstuff to execute the callable.
If all you want is syntactic sugar for invoking the lambda, you can always do what something like Alexandrescu's SCOPE_GUARD does, and abuse operator overloading:
Live example
#include <iostream>
namespace detail {
enum class invoke_t{};
template<class Callable>
auto operator+(invoke_t, Callable c) -> decltype(c()) {
return c();
}
}
constexpr detail::invoke_t invoke{};
int main() {
invoke + []() {
std::cout << "called";
};
}
But I wouldn't. Inventing your own DSL will just make your code worse to maintain. Stick to the idioms that utilize plain language constructs.
Is there a better way
You could also consider having a private static member function building the complexstuff, something like
class MyFoo : public Base {
private:
static SomeComplexType compute_complex_stuff() {
SomeComplexType complexstuff;
/*compute the complexstuff */
return complexstuff;
};
public:
MyFoo() : Base(compute_complex_stuff()) {};
};
I don't know if it is better than defining a lambda expression and applying it immediately; that is IMHO a matter of taste; for a short lambda body I would prefer a lambda expression immediately applied (but perhaps some compiler would create the temporary closure in that case, so it might be slower without optimizations; I expect most C++11 compilers to be able to make that optimization).
BTW, GCC provides the statement expression language extension (also understood by Clang) for your purposes. With it you could write
MyFoo::MyFoo : Base (({
SomeComplexType complexstuff;
/*compute the complexstuff */
return complexstuff;
}) {};
I've been using function pointers till now, like this format in c++. I do have some uses now and then and I'm wondering is there anything else introduced in c++11/14 as their alternative.
#include <iostream>
using namespace std;
void sayHello();
void someFunction(void f());
int main() {
someFunction(sayHello);
return 0;
}
void sayHello(){
std::cout<<"\n Hello World";
}
void someFunction(void f()){
f();
}
I did take a look at this question but couldn't understand any advantages over traditional use of function pointers. Also I would like to ask , is there anything wrong (not recommended) thing with using function pointers since I never see anyone using them. Or any other alternative present.
The question you mention suggest std::function but does not emphasize (or mentions at all) its value when combined with std::bind.
Your example is the simplest possible, but suppose you have a
std::function<void (int, int)> f ;
A function pointer can do more or less the same things. But suppose that you need a function g(int) which is f with second parameter bound to 0. With function pointers you can't do much, with std::function you can do this:
std::function<void(int)> g = std::bind(f, _1, 0) ;
As an alternative to traditional function pointers, C++11 introduced template alias which combined with variadic templates could simplify the function pointer sintax. below, an example of how to create a "template" function pointer:
template <typename R, typename ...ARGS> using function = R(*)(ARGS...);
It can be used this way:
void foo() { ... }
int bar(int) { ... }
double baz(double, float) { ... }
int main()
{
function<void> f1 = foo;
function<int, int> f2 = bar;
function<double, double, float> f3 = baz;
f1(); f2({}); f3({}, {});
return 0;
}
Also, it can deal neatly with function overloads:
void overloaded(int) { std::cout << "int version\n"; }
void overloaded(double) { std::cout << "double version\n"; }
int main()
{
function<void, int> f4 = overloaded;
function<void, double> f5 = overloaded;
f4({}); // int version
f5({}); // double version
return 0;
}
And can be used as a pretty neat way to declare function-pointers parameters:
void callCallback(function<int, int> callback, int value)
{
std::cout << "Calling\n";
std::cout << "v: " << callback(value) << '\n';
std::cout << "Called\n";
}
int main()
{
function<int, int> f2 = bar;
callCallback(f2, {});
return 0;
}
This template alias could be used as an alternative of std::function which doesn't have its drawbacks nor its advantages (good explanation here).
Live demo
As a brief, I think that template alias combined with variadic templates is a good, nice, neat and modern C++ alternative to raw function pointers (this alias still are function pointers after all) but std::function is good, nice, neat and modern C++ as well with good advantages to take into account. To stick in function pointers (or alias) or to choose std::function is up to your implementation needs.
Also I would like to ask , is there anything wrong (not recommended)
thing with using function pointers since I never see anyone using
them.
Yes. Function pointers are terrible, awful things. Firstly, they do not support being generic- so you cannot take a function pointer that, say, takes std::vector<T> for any T. Secondly, they do not support having bound state, so if at any time in the future, anybody, ever, wishes to refer to other state, they are completely screwed. This is especially bad since this includes this for member functions.
There are two approaches to taking functions in C++11. The first is to use a template. The second is to use std::function.
The template kinda looks like this:
template<typename T> void func(F f) {
f();
}
The main advantages here are that it accepts any kind of function object, including function pointer, lambda, functor, bind-result, whatever, and F can have any number of function call overloads with any signature, including templates, and it may have any size with any bound state. So it's super-duper flexible. It's also maximally efficient as the compiler can inline the operator and pass the state directly in the object.
int main() {
int x = 5;
func([=] { std::cout << x; });
}
The main downside here is the usual downsides of templates- it doesn't work for virtual functions and has to be defined in the header.
The other approach is std::function. std::function has many of the same advantages- it can be any size, bind to any state, and be anything callable, but trades a couple off. Mainly, the signature is fixed at type definition time, so you can't have a std::function<void(std::vector<T>)> for some yet-to-be-known T, and there may also be some dynamic indirection/allocation involved (if you can't SBO). The advantage of this is that since std::function is a real concrete type, you can pass it around as with any other object, so it can be used as a virtual function parameter and such things.
Basically, function pointers are just incredibly limited and can't really do anything interesting, and make the API incredibly unflexible. Their abominable syntax is a piss in the ocean and reducing it with a template alias is hilarious but pointless.
I did take a look at this question but couldn't understand any
advantages over traditional use of function pointers. Also I would
like to ask , is there anything wrong (not recommended) thing with
using function pointers since I never see anyone using them.
Normal "global" functions typically don't/can't have state. While it's not necessarily good to have state during traversal in functional programming paradigm, sometimes state might come in handy when it relates orthogonally to what has been changed (heuristics as example). Here functors (or function objects) have the advantage.
Normal functions don't compose very well (creating higher level functions of lower level functions.
Normal functions don't allow for binding additional parameters on the fly.
Sometimes normal functions can act as replacement for lambdas, and visa versa, depending on the context. Often one wouldn't want to write a special function just because you have some very local/specific requirement during "container traversal".
Is it possible to create a functor from a lambda function in C++?
If not, why not?
It's giving me a surprising bit of trouble to do.
Practical Use Case:
Another function requires making a functor like so:
Class::OnCallBack::MakeFunctor(this, &thisclass::function);
Typically in order to use this, I have to make a function within thisclass which means adding to the header file.
After a lot of uses, there's a good bit of bloat.
I want to avoid this bloat by doing something like:
Class::OnCallBack::MakeFunctor(this,
void callback()
{ []() { dosomething; } });
What goes wrong is compilation errors for starters.
Even if it did compile, is it possible to do something like this?
If you want to store the lambda function you could do it like this for a void() function
std::function< void() > callback = [](){ dosomething };
Or, for a function with a return type and parameters,
std::function< int( int ) > callback = []( int i ){ return dosomething(i);}
You'll need to include this file to use std::function though.
#include <functional>
You haven't specified a signature of Class::OnCallBack::MakeFunctor so I guess it's something like:
template<typename T>
Functor<T> MakeFunctor(T*, doesnt_matter (T::*)(doesnt_matter));
just because this is passed explicitly in your example.
In this case it's not a problem of C++ but of your MakeFunctor. If it would be:
template<typename F>
Functor<F> MakeFunctor(F f);
you could call it as:
Class::OnCallBack::MakeFunctor([]() { dosomething; });
There are no lambda functions in C++. The "lambda" structure in C++ defines a class with an operator(). A functor, in some. It also defines an instance of that class.
I don't know what your actual problem is, but I would guess that it has something to do with the fact that you cannot name the type of the lambda. You can usually work around this by using decltype, e.g.:
auto f = [](...) { ... };
typedef decltype( f ) LambdaType;
The other problem might be that every instance of a lambda, even identical instances, have different, unrelated types. Again, the solution is probably to create a named variable with a single instance of the lambda, using auto.
With newer C++ features, you often give a function as a parameter, for example:
// File A.cpp
void do_something(Foo* foo) { ... }
void A::process_foo(){
for_each( foo_list.begin(), foo_list.end(), do_something );
}
But where should I actually put the function do_something(...) when I work with classes? I can not make it a private member, since I would loose this when passing the parameter to for_each.
So I tend to just define a plain function do_something(...) in my implementation file A.cpp, like given in the code above. Since this is visible by the implementation of A only, I do not risk namespace pollution. Since a similiar function in other classes would also only be visible in their implementation, I also do not risk to have a name collision with a similiar function of another class.
Is this the right way?
Another idea would be to use a Lambda. I'm not very familiar with Lambdas, so I don't know whether I should use them as much as possible or only if absolutely necessary...
The third argument of std::for_each needs to be function or function object with one argument such as it may be called with an element of the range defined by first two arguments of for_each. Then you have following options (assuming that foo_list stores Foo*):
Use regular function
void do_someting(Foo*){...}
for_each(..., do_something);
You can put the function wherever it is suitable. If this is for local use, the anonymous namespace is the best option. But it may be e.g. defined in a separate compilation unit.
Use static method
static void do_something(Foo*){...}
for_each(..., &Foo::do_something);
Note that it does not need necessarily to be static method of Foo.
Use lambda
for_each(...,[](Foo* f){...});
Use a method of Foo class (even private) and std::bind
void method(){...}
for_each(..., std::bind(&Foo::method, _1));
There are other options but those are the most common.
C++11 solution
If you can use C++11, prefer range-based for instead of std::for_each and just write code in-place. Like this:
for (const auto& value : foo_list)
{
// do something with the value
}
It is less verbose and more convenient. It iterates through all of the elements one by one, just like std::for_each algorithm. And you can explicitly specify that you don't want to modify elements by putting const auto&, or simply auto (without reference).
Partial-C++11
If your compiler has no support of range-based fors, but has support of lambdas (like Visual Studio 2010), simply put function into lambda:
for_each( foo_list.begin(), foo_list.end(),
[] (const FooList::value_type& value) { /* do something with the value */; });
C++98
If you can use none of the above C++11 features, most of STL algorithms look pathetic. Whichever you place do_something function to, it will be decoupled from the calling code, which is very hard to read. Prefer simple iterator-based for in this case:
for (FooList::iterator pValue = foo_list.begin(); pValue != foo_list.end(); ++pValue)
{
// do something with the pValue
}
PS I prefer the latter form even for "Partial-C++11" case, when you cannot use range-based fors, but can replace FooList::iterator with simple auto. It is very helpful when you would have to write something more complicated, like std::list<std::string>::const_iterator. I think the following is better than std::for_each with lambda:
for (auto pValue = foo_list.begin(); pValue != foo_list.end(); ++pValue)
{
// do something with the pValue
}