54

Can I define functions in C++ inline? I am talking about lambda functions, not the inline keyword that causes a compiler optimization.

Human-Compiler
  • 11,022
  • 1
  • 32
  • 59
danijar
  • 32,406
  • 45
  • 166
  • 297

4 Answers4

75

C++11 added lambda functions to the language. The previous versions of the language (C++98 and C++03), as well as all current versions of the C language (C89, C99, and C11) do not support this feature. The syntax looks like:

[capture](parameters)->return-type{body}

For example, to compute the sum of all of the elements in a vector:

std::vector<int> some_list;
int total = 0;
for (int i=0;i<5;i++) some_list.push_back(i);
std::for_each(begin(some_list), end(some_list), [&total](int x) {
  total += x;
});
bodqhrohro
  • 119
  • 2
  • 7
Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • 9
    `int total = std::accumulate(begin(some_list), end(some_list), 0);` :) – Xeo Sep 18 '12 at 19:41
  • 1
    Any particular reason this was downvoted? It answers the question just fine. – chris Sep 18 '12 at 19:44
  • Isn't the code missing a `mutable`? IIRC lambdas take captures as `const` by default, so it should be `[&total](int x) mutable`. – Grizzly Sep 18 '12 at 19:47
  • 1
    @Grizzly: That's only interesting for by-value captures, since `const`ness doesn't propagate through indirection. – Xeo Sep 18 '12 at 19:48
  • Where is `begin(...)` and `end(...)` are defined? Are they macros for vector.begin() and vector.end() ? –  Sep 18 '12 at 19:55
  • 1
    @Desolator : They're in namespace `std`, found by ADL. And yes, they wrap `some_list.begin()` and `some_list.end()` in this case. – ildjarn Sep 18 '12 at 20:10
  • note that polymorphic lambdas are not part of c++11 – jiggunjer Jul 09 '15 at 16:57
35

In C++11, you can use closures:

void foo()
{
   auto f = [](int a, int b) -> int { return a + b; };

   auto n = f(1, 2);
}

Prior to that, you can use local classes:

void bar()
{
   struct LocalClass
   {
       int operator()(int a, int b) const { return a + b; }
   } f;

   int n = f(1, 2);
}

Both versions can be made to refer to ambient variables: In the local class, you can add a reference member and bind it in the constructor; and for the closure you can add a capture list to the lambda expression.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
10

i dont know if i understand you well, but you want a lambda function?

http://en.cppreference.com/w/cpp/language/lambda

#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>


    int main()
    {
        std::vector<int> c { 1,2,3,4,5,6,7 };
        int x = 5;
        c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; } ), c.end());

        std::cout << "c: ";
        for (auto i: c) {
            std::cout << i << ' ';
        }
        std::cout << '\n';

        std::function<int (int)> func = [](int i) { return i+4; };
        std::cout << "func: " << func(6) << '\n'; 
    }

if you dont have c++11x then try:

http://www.boost.org/doc/libs/1_51_0/doc/html/lambda.html

CyberGuy
  • 2,783
  • 1
  • 21
  • 31
7

Pre C++11, if you want to localize a function to a function, that can be done:

int foo () {
    struct Local {
        static int bar () {
            return 1;
        }
    };
    return Local::bar();
}

or if you want something more complicated:

int foo (int x) {
    struct Local {
        int & x;
        Local (int & x) : x(x) {}
        int bar (int y) {
            return x * x + y;
        }
    };
    return Local(x).bar(44);
}

But if you want a true function literal in pre C++11, that is not possible.

Thomas Eding
  • 35,312
  • 13
  • 75
  • 106