Consider the followng code
#include <iostream>
#include <functional>
using namespace std;
inline void readandrun(function<void(int)> callback) {
int i;
i = 1;
callback(i);
}
int main(int argc, char *argv[])
{
#ifdef LAMBDA
readandrun([](int i){ printf("the read number is: %d\n",i);});
#else
int i;
i = 1;
printf("the read number is: %d\n",i);
#endif
return 0;
}
Compiling with
g++ -DLAMBDA -O2 -std=c++17 -S test.cpp -o test_long.S
Yields code involving jumps while
g++ -O2 -std=c++17 -S test.cpp -o test_short.S
Does not. Which kind of makes sense but is it possible to tell the compiler to inline the lambda argument since it's known at compile time? I would be willing to switch compilers but for completeness:
$ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
If you can allow to take function pointer instead of std::function
as your argument, you can make your function constexpr
:
constexpr void readandrun(void(*callback)(int)) {
int i = 1; // can't use uninitialized variables in constexpr function
callback(i);
}
Note that only non-capturing lambdas can be converted to function pointers. For capturing lambdas see Fureeish's answer. Also, constexpr
functions have some limitations, but on the other hand compiler will execute them at compile time if possible.