this piece of code is not something unknown to JS developers
function get_counter()
{
return (
function() {
var c = 0;
return function() { return ++c; };
})();
}
it basically creates a which creates different enumerators. So I was wondering if same thing can be done in C++11 with new lambda semantics? I ended up writing this piece of C++ which unfortunately does not compile!
int main()
{
int c;
auto a = [](){
int c = 0;
return [&](){
cout << c++;
};
};
return 0;
}
so I was wondering if there is a workaround to get it compiled and if there is how can compiler make this code run correctly? I mean it has to create separate enumerators but it should also collect garbage (unused c variables).
by the way I'm using VS2012 compiler and it generates this error:
Error 2 error C2440: 'return' : cannot convert from 'main::<lambda_10d109c73135f5c106ecbfa8ff6f4b6b>::()::<lambda_019decbc8d6cd29488ffec96883efe2a>' to 'void (__cdecl *)(void)' c:\users\ali\documents\visual studio 2012\projects\test\test\main.cpp 25 1 Test
Your code has a bug in that it contains a dangling reference; the c reference will refer to the local variable in the outer lambda, which will be destroyed when the outer lambda returns.
You should write it using a mutable by-value lambda capture:
auto a = []() {
int c = 0;
return [=]() mutable {
cout << c++;
};
};
This relies on a post-standard extension to allow multiple statements in a return-type-deducing lambda; Is there a reason on not allowing lambdas to deduce the return type if it contains more than one statement? The easiest way to fix it is to supply a parameter so that the lambda contains only a single statement:
auto a = [](int c) {
return [=]() mutable {
cout << c++;
};
};
Unfortunately default parameters aren't allowed in lambdas, so you'd have to call this as a(0). Alternatively at the cost of readability you could use a nested lambda call:
auto a = []() {
return ([](int c) {
return [=]() mutable {
cout << c++;
};
})(0);
};
The way this works is that when a executes the inner lambda copies all the referenced variables into an instance of its closure type, which here would be something like:
struct inner_lambda {
int c;
void operator()() { cout << c++; }
};
The instance of the closure type is then returned by the outer lambda, and can be invoked and will modify its copy of c when called.
Overall, your (fixed) code is translated to:
struct outer_lambda {
// no closure
struct inner_lambda {
int c; // by-value capture
// non-const because "mutable"
void operator()() { cout << c++; }
}
// const because non-"mutable"
inner_lambda operator()(int c) const {
return inner_lambda{c};
}
};
If you left c as a by-reference capture, this would be:
struct outer_lambda {
// no closure
struct inner_lambda {
int &c; // by-reference capture
void operator()() const { cout << c++; } // const, but can modify c
}
inner_lambda operator()(int c) const {
return inner_lambda{c};
}
};
Here inner_lambda::c is a dangling reference to the local parameter variable c.
It's a natural limitation of C++ that a lambda which captures by reference can't use the captured variable any more, once the variable no longer exists. So even if you get it to compile, you can't return this lambda from the function in which it appears (that also happens to be a lambda, but that's irrelevant), because the automatic variable c is destroyed on return.
I think the code you need is:
return [=]() mutable {
cout << c++;
};
I haven't tested it and I don't know what compiler versions support it, but that's a capture-by-value, with mutable to say that the captured value can be modified by the lambda.
So each time you call a you get a different counter with its own count starting from 0. Each time you call that counter, it increments its own copy of c. As far as I understand Javascript (not far), that's what you want.
I think the problem is that the compiler cannot deduce the return type of the outer lambda (that assigned to a) because it consists of more than a simple one line return. But unfortunately there is also no way to explicitly state the type of the inner lambda. So you will have to return a std::function, which comes with some additional overhead:
int main()
{
int c;
auto a = []() -> std::function<void()> {
int c = 0;
return [=]() mutable {
std::cout << c++;
};
};
return 0;
}
And of course you have to capture by-value, like Steve already explained in his answer.
EDIT: As to why the exact error is that it cannot convert the returned inner lambda to void(*)() (pointer to void() function), I only have some guesses because I don't have much insight into their lambda implementation, which I'm not sure is that stable or standard-conformant at all.
But I think VC at least tries to deduce the return type of the inner lambda and realizes that it returns a callable. But then it somehow incorrectly assumes this inner lambda to not capture (or they are not able to determine the inner lambda's type), so they just make the outer lambda return a simple function pointer, which would indeed work if the inner lambda wouldn't capture anything.
EDIT: And like ecatmur states in his comment, returning a std::function is even neccessary when making an actual get_counter function (instead of a lambda), since normal functions don't have any automatic return type deduction.
The first thing you should know is that even if you get the syntax to compile, the semantics are different. In C++ lambdas that capture by reference capture just a plain reference, that will not extend the lifetime of the object bound by that reference. That is, the lifetime of c is bound to the lifetime of the enclosing lambda:
int main()
{
int c;
auto a = [](){
int c = 0;
return [&](){
return ++c;
};
}(); // Note: added () as in the JS case
std::cout << a() << a();
return 0;
}
After adding the missing () so that the external lambda is evaluated, your problem is that the c that is held by reference in the returned lambda is no longer valid after the evaluation of the full expression.
That being said, it is not too complex to make that work at the cost of an extra dynamic allocation (which would be the equivalent of the JS case):
int main()
{
int c;
auto a = [](){
std::shared_ptr<int> c = std::make_shared<int>(0);
return [=](){
return ++(*c);
};
}(); // Note: added () as in the JS case
std::cout << a() << a();
return 0;
}
That should compile and work as expected. Whenever the internal lambda is released (a goes out of scope) the counter will be freed from memory.
This works on g++ 4.7
#include <iostream>
#include <functional>
std::function<int()> make_counter() {
return []()->std::function<int()> {
int c=0;
return [=]() mutable ->int {
return c++ ;
};
}();
}
int main(int argc, char * argv[]) {
int i = 1;
auto count1= make_counter();
auto count2= make_counter();
std::cout << "count1=" << count1() << std::endl;
std::cout << "count1=" << count1() << std::endl;
std::cout << "count2=" << count2() << std::endl;
std::cout << "count1=" << count1() << std::endl;
std::cout << "count2=" << count2() << std::endl;
return 0;
}
Valgrind doesn't complain about this at all. Every time I call make_counter, valgrind reports an additional allocation and free, so I assume the lambda meta programming code is inserting the allocation code for the memory for variable c (I guess I can check the debugger). I wonder if this is Cxx11 compliant or just g++ specific. Clang 3.0 will not compile this because it doesn't have std::function (maybe I can try using boost function).
I know this is late, but in C++14 and later you can now initiliaze a lambda capture, leading to more simple code:
auto a = []() {
return [c=0]() mutable {
cout << c++;
};
};
Related
is this the correct way to create a closure for a lambda function
#include <functional>
#include <memory>
#include <string>
#include <iostream>
using namespace std;
class A
{
function<void()> fn(string str){ // (2)
struct closure {
int num;
};
auto ptr = make_shared<closure>();
ptr->num = 99;
auto fn = [=](){
ptr->num++;
cout << ptr->num << " -- " << str << endl;
};//fn
return fn;
}//fn
};//A
A a;
int main(){
auto fn = a.fn("1");
fn();
fn();
auto fn2 = a.fn("2");
fn2();
fn2();
}//main
view code -> online c++ compiler
the arguments to the function that creates the lambda #(2) dont seem to be needed within the closure, is this actually true?
what are the caveats to using this approach, heap/stack = creme fraiche, do i need to release the memory?
what practical difference would it make to capture by reference within the lambda?
edit
maybe i over simplified, sometimes the function looks like this
class A {
void fn(string str){
struct closure {
int num;
int token;
};
auto ptr = make_shared<closure>();
ptr->num = 100;
auto fn = [=](){
ptr->num++;
cout << str << ptr->num << endl;
if(ptr->num==105){
list.rem(ptr->token); // <= defined elsewhere
}
};
ptr->token = list.add(fn); // <= defined elsewhere
}//fn
};//A
is this the correct way to create a closure for a lambda function?
Your lambda can be simplified to:
function<void()> fn(string str){
return [str, i = 99]() mutable {
++i;
std::cout << i << " -- " << str << std::endl;
};
}
do I need to release the memory?
You capture a std::shared_ptr by value, it would release its memory on destruction, you are fine.
what practical difference would it make to capture by reference within the lambda?
As you capture local variable, capturing by reference would lead to dangling pointer.
It looks like it isn't wrong, but for what it is also looks like massive overkill.
You could accomplish the same thing without using sharerd_ptr or any dynamic memory, by simply capturing an int and making the lambda mutable:
std::function<void()> fn(std::string str){ // (2)
return [=, num = 99]() mutable {
num++;
std::cout << num << " -- " << str << "\n";
};
}
If you plan to copy your lambda and have both copies affect the same underlying data, OR, you hold onto that shared pointer and do more things with it, possibly after returning the lambda, then perhaps your approach makes more sense. A custom struct and shared ptr is heavy and I prefer simple whenever possible.
Also, the by-value / by-reference question is important, since str is printed out in the lambda, it needs to be sure that the object it uses continues to live. Since it is a function parameter, the argument will be destroyed when the function returns, so the lambda must not store a reference to it, or it'll be to a destructed object and cause undefined behavior if it's called. You need the copy to preserve the string so it's guaranteed to be valid when the lambda is called.
I mean something like:
int main()
{
void a()
{
// code
}
a();
return 0;
}
Modern C++ - Yes with lambdas!
In current versions of c++ (C++11, C++14, and C++17), you can have functions inside functions in the form of a lambda:
int main() {
// This declares a lambda, which can be called just like a function
auto print_message = [](std::string message)
{
std::cout << message << "\n";
};
// Prints "Hello!" 10 times
for(int i = 0; i < 10; i++) {
print_message("Hello!");
}
}
Lambdas can also modify local variables through **capture-by-reference*. With capture-by-reference, the lambda has access to all local variables declared in the lambda's scope. It can modify and change them normally.
int main() {
int i = 0;
// Captures i by reference; increments it by one
auto addOne = [&] () {
i++;
};
while(i < 10) {
addOne(); //Add 1 to i
std::cout << i << "\n";
}
}
C++98 and C++03 - Not directly, but yes with static functions inside local classes
C++ doesn't support that directly.
That said, you can have local classes, and they can have functions (non-static or static), so you can get this to some extend, albeit it's a bit of a kludge:
int main() // it's int, dammit!
{
struct X { // struct's as good as class
static void a()
{
}
};
X::a();
return 0;
}
However, I'd question the praxis. Everyone knows (well, now that you do, anyway :)) C++ doesn't support local functions, so they are used to not having them. They are not used, however, to that kludge. I would spend quite a while on this code to make sure it's really only there to allow local functions. Not good.
For all intents and purposes, C++ supports this via lambdas:1
int main() {
auto f = []() { return 42; };
std::cout << "f() = " << f() << std::endl;
}
Here, f is a lambda object that acts as a local function in main. Captures can be specified to allow the function to access local objects.
Behind the scenes, f is a function object (i.e. an object of a type that provides an operator()). The function object type is created by the compiler based on the lambda.
1 since C++11
Local classes have already been mentioned, but here is a way to let them appear even more as local functions, using an operator() overload and an anonymous class:
int main() {
struct {
unsigned int operator() (unsigned int val) const {
return val<=1 ? 1 : val*(*this)(val-1);
}
} fac;
std::cout << fac(5) << '\n';
}
I don't advise on using this, it's just a funny trick (can do, but imho shouldn't).
2014 Update:
With the rise of C++11 a while back, you can now have local functions whose syntax is a little reminiscient of JavaScript:
auto fac = [] (unsigned int val) {
return val*42;
};
For a recursive function, compile-time type deduction is not supported:
function<int(int)> factorial{ [&](int n)
{
return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
} };
You can't have local functions in C++. However, C++11 has lambdas. Lambdas are basically variables that work like functions.
A lambda has the type std::function (actually that's not quite true, but in most cases you can suppose it is). To use this type, you need to #include <functional>. std::function is a template, taking as template argument the return type and the argument types, with the syntax std::function<ReturnType(ArgumentTypes)>. For example, std::function<int(std::string, float)> is a lambda returning an int and taking two arguments, one std::string and one float. The most common one is std::function<void()>, which returns nothing and takes no arguments.
Once a lambda is declared, it is called just like a normal function, using the syntax lambda(arguments).
To define a lambda, use the syntax [captures](arguments){code} (there are other ways of doing it, but I won't mention them here). arguments is what arguments the lambda takes, and code is the code that should be run when the lambda is called. Usually you put [=] or [&] as captures. [=] means that you capture all variables in the scope in which the value is defined by value, which means that they will keep the value that they had when the lambda was declared. [&] means that you capture all variables in the scope by reference, which means that they will always have their current value, but if they are erased from memory the program will crash. Here are some examples:
#include <functional>
#include <iostream>
int main(){
int x = 1;
std::function<void()> lambda1 = [=](){
std::cout << x << std::endl;
};
std::function<void()> lambda2 = [&](){
std::cout << x << std::endl;
};
x = 2;
lambda1(); //Prints 1 since that was the value of x when it was captured and x was captured by value with [=]
lambda2(); //Prints 2 since that's the current value of x and x was captured by reference with [&]
std::function<void()> lambda3 = [](){}, lambda4 = [](){}; //I prefer to initialize these since calling an uninitialized lambda is undefined behavior.
//[](){} is the empty lambda.
{
int y = 3; //y will be deleted from the memory at the end of this scope
lambda3 = [=](){
std::cout << y << endl;
};
lambda4 = [&](){
std::cout << y << endl;
};
}
lambda3(); //Prints 3, since that's the value y had when it was captured
lambda4(); //Causes the program to crash, since y was captured by reference and y doesn't exist anymore.
//This is a bit like if you had a pointer to y which now points nowhere because y has been deleted from the memory.
//This is why you should be careful when capturing by reference.
return 0;
}
You can also capture specific variables by specifying their names. Just specifying their name will capture them by value, specifying their name with a & before will capture them by reference. For example, [=, &foo] will capture all variables by value except foo which will be captured by reference, and [&, foo] will capture all variables by reference except foo which will be captured by value. You can also capture only specific variables, for example [&foo] will capture foo by reference and will capture no other variables. You can also capture no variables at all by using []. If you try to use a variable in a lambda that you didn't capture, it won't compile. Here is an example:
#include <functional>
int main(){
int x = 4, y = 5;
std::function<void(int)> myLambda = [y](int z){
int xSquare = x * x; //Compiler error because x wasn't captured
int ySquare = y * y; //OK because y was captured
int zSquare = z * z; //OK because z is an argument of the lambda
};
return 0;
}
You can't change the value of a variable that was captured by value inside a lambda (variables captured by value have a const type inside the lambda). To do so, you need to capture the variable by reference. Here is an exampmle:
#include <functional>
int main(){
int x = 3, y = 5;
std::function<void()> myLambda = [x, &y](){
x = 2; //Compiler error because x is captured by value and so it's of type const int inside the lambda
y = 2; //OK because y is captured by reference
};
x = 2; //This is of course OK because we're not inside the lambda
return 0;
}
Also, calling uninitialized lambdas is undefined behavior and will usually cause the program to crash. For example, never do this:
std::function<void()> lambda;
lambda(); //Undefined behavior because lambda is uninitialized
Examples
Here is the code for what you wanted to do in your question using lambdas:
#include <functional> //Don't forget this, otherwise you won't be able to use the std::function type
int main(){
std::function<void()> a = [](){
// code
}
a();
return 0;
}
Here is a more advanced example of a lambda:
#include <functional> //For std::function
#include <iostream> //For std::cout
int main(){
int x = 4;
std::function<float(int)> divideByX = [x](int y){
return (float)y / (float)x; //x is a captured variable, y is an argument
}
std::cout << divideByX(3) << std::endl; //Prints 0.75
return 0;
}
No.
What are you trying to do?
workaround:
int main(void)
{
struct foo
{
void operator()() { int a = 1; }
};
foo b;
b(); // call the operator()
}
Starting with C++ 11 you can use proper lambdas. See the other answers for more details.
Old answer: You can, sort-of, but you have to cheat and use a dummy class:
void moo()
{
class dummy
{
public:
static void a() { printf("I'm in a!\n"); }
};
dummy::a();
dummy::a();
}
No, it's not allowed. Neither C nor C++ support this feature by default, however TonyK points out (in the comments) that there are extensions to the GNU C compiler that enable this behavior in C.
You cannot define a free function inside another in C++.
As others have mentioned, you can use nested functions by using the gnu language extensions in gcc. If you (or your project) sticks to the gcc toolchain, your code will be mostly portable across the different architectures targeted by the gcc compiler.
However, if there is a possible requirement that you might need to compile code with a different toolchain, then I'd stay away from such extensions.
I'd also tread with care when using nested functions. They are a beautiful solution for managing the structure of complex, yet cohesive blocks of code (the pieces of which are not meant for external/general use.) They are also very helpful in controlling namespace pollution (a very real concern with naturally complex/long classes in verbose languages.)
But like anything, they can be open to abuse.
It is sad that C/C++ does not support such features as an standard. Most pascal variants and Ada do (almost all Algol-based languages do). Same with JavaScript. Same with modern languages like Scala. Same with venerable languages like Erlang, Lisp or Python.
And just as with C/C++, unfortunately, Java (with which I earn most of my living) does not.
I mention Java here because I see several posters suggesting usage of classes and class' methods as alternatives to nested functions. And that's also the typical workaround in Java.
Short answer: No.
Doing so tend to introduce artificial, needless complexity on a class hierarchy. With all things being equal, the ideal is to have a class hierarchy (and its encompassing namespaces and scopes) representing an actual domain as simple as possible.
Nested functions help deal with "private", within-function complexity. Lacking those facilities, one should try to avoid propagating that "private" complexity out and into one's class model.
In software (and in any engineering discipline), modeling is a matter of trade-offs. Thus, in real life, there will be justified exceptions to those rules (or rather guidelines). Proceed with care, though.
All this tricks just look (more or less) as local functions, but they don't work like that. In a local function you can use local variables of it's super functions. It's kind of semi-globals. Non of these tricks can do that. The closest is the lambda trick from c++0x, but it's closure is bound in definition time, not the use time.
Let me post a solution here for C++03 that I consider the cleanest possible.*
#define DECLARE_LAMBDA(NAME, RETURN_TYPE, FUNCTION) \
struct { RETURN_TYPE operator () FUNCTION } NAME;
...
int main(){
DECLARE_LAMBDA(demoLambda, void, (){
cout<<"I'm a lambda!"<<endl;
});
demoLambda();
DECLARE_LAMBDA(plus, int, (int i, int j){
return i+j;
});
cout << "plus(1,2)=" << plus(1,2) << endl;
return 0;
}
(*) in the C++ world using macros is never considered clean.
But we can declare a function inside main():
int main()
{
void a();
}
Although the syntax is correct, sometimes it can lead to the "Most vexing parse":
#include <iostream>
struct U
{
U() : val(0) {}
U(int val) : val(val) {}
int val;
};
struct V
{
V(U a, U b)
{
std::cout << "V(" << a.val << ", " << b.val << ");\n";
}
~V()
{
std::cout << "~V();\n";
}
};
int main()
{
int five = 5;
V v(U(five), U());
}
=> no program output.
(Only Clang warning after compilation).
C++'s most vexing parse again
Yes, and you can do things with them that even C++20 Lambdas don't support. Namely, pure recursive calls to themselves & related functions.
For example, the Collatz Conjecture is that a certain simple recursive function will ultimately produce "1" for ANY positive integer N. Using an explicit local struct and functions, I can write a single self-contained function to run the test for any "N".
constexpr std::optional<int> testCollatzConjecture(int N) {
struct CollatzCallbacks {
constexpr static int onEven(int n) {
return recurse(n >> 1); // AKA "n/2"
}
constexpr static int onOdd(int n) {
if(n==1) return 1; // Break recursion. n==1 is only possible when n is odd.
return recurse(3 * n + 1);
}
constexpr static int recurse(int n) {
return (n%2) ? onOdd(n) : onEven(n); // (n%2) == 1 when n is odd
}
};
// Error check
if(N < 0) return {};
// Recursive call.
return CollatzCallbacks::recurse(N);
}
Notice some things that even c++20 lambdas couldn't do here:
I didn't need std::function<> glue OR lambda captures ("[&]") just to enable my local recursive functions call themselves, or each other. I needed 3 plain-old-functions with names, and that's all I had to write.
My code is more readable and (due to (1)) will also run much faster.
I cleanly separate the recursive logic in "CollatzCallbacks" from the rest of "testCollatzConjecture". It all runs in an isolated sandbox.
I was able to make everything "constexpr" and state-less, so it can all run at compile time for any constant value. AFAIK I'd need c++23 just to achieve the recursion part with state-less lambdas.
Remember: Lambda functions are really just compiler-generated local structs like "CollatzCallbacks", only they're unnamed and only have a single "operator()" member function. You can always write more complex local structs and functions directly, especially in cases like this where you really need them.
I wonder if it is possible to do this in C ++?
e.g:
varFunction = void TestFunction();
RunCode(varFunction);
With C++11 and higher, you can use the std::function to store function pointers and function objects.
But storing function pointers was available in C++ from the start. This means you can store the address of a function and call it later.
BTW, lambda expressions are also very useful (and the closure they are denoting could be assigned or passed as std::function-s)
Here is an example showing three different ways to achieve what did you asked for:
#include <iostream>
#include <functional>
void RunCode(const std::function<void()>& callable) {
callable();
}
void TestFunction() {
std::cout << "TestFunction is called..." << std::endl;
}
int main() {
std::function<void()> varFunction_1 = TestFunction;
void (*varFunction_2)() = TestFunction;
RunCode(varFunction_1);
RunCode(varFunction_2);
RunCode([]() { std::cout << "TestLambda is called..." << std::endl; });
return 0;
}
But this is just the tip of the iceberg, passing function pointers and function objects as parameters is very common in the algorithms library.
C++ provides several ways to do it.
For example, you can use std::function template: include <functional> and use the following syntax (demo):
std::function<void()> varFunction(TestFunction);
varFunction();
You can also use function pointers (Q&A on the topic).
For the sake of completeness, you can declare a C-style function type as follows:
typedef int (*inttoint)(int);
This creates a type inttoint that can store any function that takes an int as parameter and returns an int. You can use it as follows.
// Define a function
int square(int x) { return x*x; }
// Save the function in sq variable
inttoint sq { square };
// Execute the function
sq(4);
Since C++11, these variables can also store lambda functions, like so
inttoint half { [](int x) { return x/2; } };
And use it same as above.
The easiest way is to use a lambda expression like this:
auto add = [](int a, int b) { return a+b; };
cout << add(10, 20) << endl; // Output: 30
More info about how lambda expressions work: http://en.cppreference.com/w/cpp/language/lambda
This works on g++ 4.7
#include <iostream>
#include <functional>
std::function<int()> make_counter() {
return []()->std::function<int()> {
int c=0;
return [=]() mutable ->int {
return c++ ;
};
}();
}
int main(int argc, char * argv[]) {
auto count1= make_counter();
auto count2= make_counter();
std::cout << "count1=" << count1() << std::endl;
std::cout << "count1=" << count1() << std::endl;
std::cout << "count2=" << count2() << std::endl;
std::cout << "count1=" << count1() << std::endl;
std::cout << "count2=" << count2() << std::endl;
return 0;
}
It seems like I should be able to do this because c no longer exists after make_function returns, but it is does
count1=0
count1=1
count1=2
count2=0
count1=3
count2=1
I'm guessing that the [=] makes it so the value of c stored and mutable is allows for the stored value to modified though I just want to make sure.
Valgrind doesn't complain about this at all. Every time I call make_counter, valgrind reports an additional allocation and free, so I assume the lambda meta programming code is inserting the allocation code for the memory for variable . I'm wonder if this is Cxx11 compliant or if it's just g++ specific.
assuming the answer is correct, I could simplify make_counter to
std::function<int()> make_counter() {
int c=0 ;
return [=]() mutable ->int {
return c++ ;
};
}
Yes it is.
By specifying [=] you made a copy of the local variable, and that copy is stashed, somewhere, in the lambda. The expression c++ uses that local copy, which will live as long as the lambda does.
Note that the mutable would not have been necessary had c being referencing an external variable; its presence is made necessary by the fact that c is captured by copy and thus lives within the lambda "body".
I mean something like:
int main()
{
void a()
{
// code
}
a();
return 0;
}
Modern C++ - Yes with lambdas!
In current versions of c++ (C++11, C++14, and C++17), you can have functions inside functions in the form of a lambda:
int main() {
// This declares a lambda, which can be called just like a function
auto print_message = [](std::string message)
{
std::cout << message << "\n";
};
// Prints "Hello!" 10 times
for(int i = 0; i < 10; i++) {
print_message("Hello!");
}
}
Lambdas can also modify local variables through **capture-by-reference*. With capture-by-reference, the lambda has access to all local variables declared in the lambda's scope. It can modify and change them normally.
int main() {
int i = 0;
// Captures i by reference; increments it by one
auto addOne = [&] () {
i++;
};
while(i < 10) {
addOne(); //Add 1 to i
std::cout << i << "\n";
}
}
C++98 and C++03 - Not directly, but yes with static functions inside local classes
C++ doesn't support that directly.
That said, you can have local classes, and they can have functions (non-static or static), so you can get this to some extend, albeit it's a bit of a kludge:
int main() // it's int, dammit!
{
struct X { // struct's as good as class
static void a()
{
}
};
X::a();
return 0;
}
However, I'd question the praxis. Everyone knows (well, now that you do, anyway :)) C++ doesn't support local functions, so they are used to not having them. They are not used, however, to that kludge. I would spend quite a while on this code to make sure it's really only there to allow local functions. Not good.
For all intents and purposes, C++ supports this via lambdas:1
int main() {
auto f = []() { return 42; };
std::cout << "f() = " << f() << std::endl;
}
Here, f is a lambda object that acts as a local function in main. Captures can be specified to allow the function to access local objects.
Behind the scenes, f is a function object (i.e. an object of a type that provides an operator()). The function object type is created by the compiler based on the lambda.
1 since C++11
Local classes have already been mentioned, but here is a way to let them appear even more as local functions, using an operator() overload and an anonymous class:
int main() {
struct {
unsigned int operator() (unsigned int val) const {
return val<=1 ? 1 : val*(*this)(val-1);
}
} fac;
std::cout << fac(5) << '\n';
}
I don't advise on using this, it's just a funny trick (can do, but imho shouldn't).
2014 Update:
With the rise of C++11 a while back, you can now have local functions whose syntax is a little reminiscient of JavaScript:
auto fac = [] (unsigned int val) {
return val*42;
};
For a recursive function, compile-time type deduction is not supported:
function<int(int)> factorial{ [&](int n)
{
return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
} };
You can't have local functions in C++. However, C++11 has lambdas. Lambdas are basically variables that work like functions.
A lambda has the type std::function (actually that's not quite true, but in most cases you can suppose it is). To use this type, you need to #include <functional>. std::function is a template, taking as template argument the return type and the argument types, with the syntax std::function<ReturnType(ArgumentTypes)>. For example, std::function<int(std::string, float)> is a lambda returning an int and taking two arguments, one std::string and one float. The most common one is std::function<void()>, which returns nothing and takes no arguments.
Once a lambda is declared, it is called just like a normal function, using the syntax lambda(arguments).
To define a lambda, use the syntax [captures](arguments){code} (there are other ways of doing it, but I won't mention them here). arguments is what arguments the lambda takes, and code is the code that should be run when the lambda is called. Usually you put [=] or [&] as captures. [=] means that you capture all variables in the scope in which the value is defined by value, which means that they will keep the value that they had when the lambda was declared. [&] means that you capture all variables in the scope by reference, which means that they will always have their current value, but if they are erased from memory the program will crash. Here are some examples:
#include <functional>
#include <iostream>
int main(){
int x = 1;
std::function<void()> lambda1 = [=](){
std::cout << x << std::endl;
};
std::function<void()> lambda2 = [&](){
std::cout << x << std::endl;
};
x = 2;
lambda1(); //Prints 1 since that was the value of x when it was captured and x was captured by value with [=]
lambda2(); //Prints 2 since that's the current value of x and x was captured by reference with [&]
std::function<void()> lambda3 = [](){}, lambda4 = [](){}; //I prefer to initialize these since calling an uninitialized lambda is undefined behavior.
//[](){} is the empty lambda.
{
int y = 3; //y will be deleted from the memory at the end of this scope
lambda3 = [=](){
std::cout << y << endl;
};
lambda4 = [&](){
std::cout << y << endl;
};
}
lambda3(); //Prints 3, since that's the value y had when it was captured
lambda4(); //Causes the program to crash, since y was captured by reference and y doesn't exist anymore.
//This is a bit like if you had a pointer to y which now points nowhere because y has been deleted from the memory.
//This is why you should be careful when capturing by reference.
return 0;
}
You can also capture specific variables by specifying their names. Just specifying their name will capture them by value, specifying their name with a & before will capture them by reference. For example, [=, &foo] will capture all variables by value except foo which will be captured by reference, and [&, foo] will capture all variables by reference except foo which will be captured by value. You can also capture only specific variables, for example [&foo] will capture foo by reference and will capture no other variables. You can also capture no variables at all by using []. If you try to use a variable in a lambda that you didn't capture, it won't compile. Here is an example:
#include <functional>
int main(){
int x = 4, y = 5;
std::function<void(int)> myLambda = [y](int z){
int xSquare = x * x; //Compiler error because x wasn't captured
int ySquare = y * y; //OK because y was captured
int zSquare = z * z; //OK because z is an argument of the lambda
};
return 0;
}
You can't change the value of a variable that was captured by value inside a lambda (variables captured by value have a const type inside the lambda). To do so, you need to capture the variable by reference. Here is an exampmle:
#include <functional>
int main(){
int x = 3, y = 5;
std::function<void()> myLambda = [x, &y](){
x = 2; //Compiler error because x is captured by value and so it's of type const int inside the lambda
y = 2; //OK because y is captured by reference
};
x = 2; //This is of course OK because we're not inside the lambda
return 0;
}
Also, calling uninitialized lambdas is undefined behavior and will usually cause the program to crash. For example, never do this:
std::function<void()> lambda;
lambda(); //Undefined behavior because lambda is uninitialized
Examples
Here is the code for what you wanted to do in your question using lambdas:
#include <functional> //Don't forget this, otherwise you won't be able to use the std::function type
int main(){
std::function<void()> a = [](){
// code
}
a();
return 0;
}
Here is a more advanced example of a lambda:
#include <functional> //For std::function
#include <iostream> //For std::cout
int main(){
int x = 4;
std::function<float(int)> divideByX = [x](int y){
return (float)y / (float)x; //x is a captured variable, y is an argument
}
std::cout << divideByX(3) << std::endl; //Prints 0.75
return 0;
}
No.
What are you trying to do?
workaround:
int main(void)
{
struct foo
{
void operator()() { int a = 1; }
};
foo b;
b(); // call the operator()
}
Starting with C++ 11 you can use proper lambdas. See the other answers for more details.
Old answer: You can, sort-of, but you have to cheat and use a dummy class:
void moo()
{
class dummy
{
public:
static void a() { printf("I'm in a!\n"); }
};
dummy::a();
dummy::a();
}
No, it's not allowed. Neither C nor C++ support this feature by default, however TonyK points out (in the comments) that there are extensions to the GNU C compiler that enable this behavior in C.
You cannot define a free function inside another in C++.
As others have mentioned, you can use nested functions by using the gnu language extensions in gcc. If you (or your project) sticks to the gcc toolchain, your code will be mostly portable across the different architectures targeted by the gcc compiler.
However, if there is a possible requirement that you might need to compile code with a different toolchain, then I'd stay away from such extensions.
I'd also tread with care when using nested functions. They are a beautiful solution for managing the structure of complex, yet cohesive blocks of code (the pieces of which are not meant for external/general use.) They are also very helpful in controlling namespace pollution (a very real concern with naturally complex/long classes in verbose languages.)
But like anything, they can be open to abuse.
It is sad that C/C++ does not support such features as an standard. Most pascal variants and Ada do (almost all Algol-based languages do). Same with JavaScript. Same with modern languages like Scala. Same with venerable languages like Erlang, Lisp or Python.
And just as with C/C++, unfortunately, Java (with which I earn most of my living) does not.
I mention Java here because I see several posters suggesting usage of classes and class' methods as alternatives to nested functions. And that's also the typical workaround in Java.
Short answer: No.
Doing so tend to introduce artificial, needless complexity on a class hierarchy. With all things being equal, the ideal is to have a class hierarchy (and its encompassing namespaces and scopes) representing an actual domain as simple as possible.
Nested functions help deal with "private", within-function complexity. Lacking those facilities, one should try to avoid propagating that "private" complexity out and into one's class model.
In software (and in any engineering discipline), modeling is a matter of trade-offs. Thus, in real life, there will be justified exceptions to those rules (or rather guidelines). Proceed with care, though.
All this tricks just look (more or less) as local functions, but they don't work like that. In a local function you can use local variables of it's super functions. It's kind of semi-globals. Non of these tricks can do that. The closest is the lambda trick from c++0x, but it's closure is bound in definition time, not the use time.
Let me post a solution here for C++03 that I consider the cleanest possible.*
#define DECLARE_LAMBDA(NAME, RETURN_TYPE, FUNCTION) \
struct { RETURN_TYPE operator () FUNCTION } NAME;
...
int main(){
DECLARE_LAMBDA(demoLambda, void, (){
cout<<"I'm a lambda!"<<endl;
});
demoLambda();
DECLARE_LAMBDA(plus, int, (int i, int j){
return i+j;
});
cout << "plus(1,2)=" << plus(1,2) << endl;
return 0;
}
(*) in the C++ world using macros is never considered clean.
But we can declare a function inside main():
int main()
{
void a();
}
Although the syntax is correct, sometimes it can lead to the "Most vexing parse":
#include <iostream>
struct U
{
U() : val(0) {}
U(int val) : val(val) {}
int val;
};
struct V
{
V(U a, U b)
{
std::cout << "V(" << a.val << ", " << b.val << ");\n";
}
~V()
{
std::cout << "~V();\n";
}
};
int main()
{
int five = 5;
V v(U(five), U());
}
=> no program output.
(Only Clang warning after compilation).
C++'s most vexing parse again
Yes, and you can do things with them that even C++20 Lambdas don't support. Namely, pure recursive calls to themselves & related functions.
For example, the Collatz Conjecture is that a certain simple recursive function will ultimately produce "1" for ANY positive integer N. Using an explicit local struct and functions, I can write a single self-contained function to run the test for any "N".
constexpr std::optional<int> testCollatzConjecture(int N) {
struct CollatzCallbacks {
constexpr static int onEven(int n) {
return recurse(n >> 1); // AKA "n/2"
}
constexpr static int onOdd(int n) {
if(n==1) return 1; // Break recursion. n==1 is only possible when n is odd.
return recurse(3 * n + 1);
}
constexpr static int recurse(int n) {
return (n%2) ? onOdd(n) : onEven(n); // (n%2) == 1 when n is odd
}
};
// Error check
if(N < 0) return {};
// Recursive call.
return CollatzCallbacks::recurse(N);
}
Notice some things that even c++20 lambdas couldn't do here:
I didn't need std::function<> glue OR lambda captures ("[&]") just to enable my local recursive functions call themselves, or each other. I needed 3 plain-old-functions with names, and that's all I had to write.
My code is more readable and (due to (1)) will also run much faster.
I cleanly separate the recursive logic in "CollatzCallbacks" from the rest of "testCollatzConjecture". It all runs in an isolated sandbox.
I was able to make everything "constexpr" and state-less, so it can all run at compile time for any constant value. AFAIK I'd need c++23 just to achieve the recursion part with state-less lambdas.
Remember: Lambda functions are really just compiler-generated local structs like "CollatzCallbacks", only they're unnamed and only have a single "operator()" member function. You can always write more complex local structs and functions directly, especially in cases like this where you really need them.