Click here to Skip to main content
Click here to Skip to main content

Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

By , 4 Nov 2011
 
Prize winner in Competition "Best C++ article of November 2011"

Introduction

For a short while it was rather disappointing as a C++ developer that you did not have lambdas while other languages like C# already had them. Of course, that's changed now and C++ not only has lambdas but C++ lambdas have greater syntactic flexibility than C# lambdas. This article will be a comparative look at the lambda usage in both languages.

Note: The article does not intend to give a comprehensive syntactic coverage of lambdas in either C# or C++. It assumes you can already use lambdas in one or both languages. The article's focus is on the differences and similarities in lambda usage across the languages and their variants.

Basic usage in C# and C++

Here's a very simple C# method that I'll use to demo C# lambdas:

static void RunFoo(Func<int, int> foo)
{
    Console.WriteLine("Result = " + foo(3) + "\r\n");
}

And here's the corresponding C++ version:

void RunFoo(function<int(int)> foo)
{
    std::cout << "Result = " << foo(3) << "\r\n\r\n";
}

Both versions take a function that has an int parameter and returns an int.  Here's a very simple C# example showing how the method is called with a lambda.

RunFoo(x => x);

Notice how the argument type as well as the return type are inferred by the compiler. Now here's the C++ version.

RunFoo( [](int x) -> int { return x; });

The argument type and return type need to be specified in C++. Well, not exactly, the following will work too.

RunFoo( [](int x) { return x; });

Notice how I've removed the return type specification. But now, if I make a small change, it will not compile anymore.

RunFoo( [](int x)  { x++; return x; });

You get the following error.

// C3499: a lambda that has been specified to have a void return type cannot return a value	

The intellisense tooltip explains what happened there.

// the body of a value-returning lambda with no explicit return type must be a single return statement	

This code will compile.

RunFoo( [](int x) -> int  { x++; return x; });

Note that this may change in a future release where the return type will be deduced even for multi-statement lambdas. It is unlikely that C++ will support type-deduction in lambda arguments though.

Capturing variables - C# vs C++

Both C# and C++ let you capture variables. C# always captures variables by reference. The following code's output will make that fairly obvious.

var foos = new List<Func<int, int>>();

for (int i = 0; i < 2; i++)
{
    foos.Add(x =>
    {
        Console.WriteLine(i);
        return i;
    });
}
foos.ForEach(foo => RunFoo(foo));
foos.Clear();

That will output:

2
Result = 2

2
Result = 2

I reckon most of you know why that happens, but if you don't here's why. Consider this very basic code snippet.

int i = 5;
RunFoo(x => i);

The compiler generates a class (pseudo-code) that looks something like below:

sealed class LambdaClass
{
    public int i;
    public LambdaClass(){}
    public int Foo(int x){ return i;}
}

And the call to RunFoo is compiled as (pseudo-code):

var local = new LambdaClass();
local.i = 5;
RunFoo(new Func<int, int>(local.Foo));

So in the earlier example, the same instance of the compiler-generated class was reused inside the for-loop for each iteration. Which explains the output. The workaround in C# is to force it to create a new instance of the lambda class each time by introducing a local variable.

for (int i = 0; i < 2; i++)
{
    int local = i;

    foos.Add(x =>
    {
        Console.WriteLine(local);
        return local;
    });
}
foos.ForEach(foo => RunFoo(foo));

This forces the compiler to create separate instances of the lambda class (there's only one generated class, with multiple instances). Now take a look at similar C++ code.

std::vector<function<int(int)>> foos;

for (int i = 0; i < 2; i++)
{
  foos.push_back([i](int x) -> int
  {
    std::cout << i << std::endl;
    return i;
  });
}

for each(auto foo in foos)
{
  RunFoo(foo);
}
foos.clear();

In C++, you can specify how a capture is made, whether by copy or by reference. In the above snippet the capture is by copy and so the code works as expected. To get the same output as the original C# code, we could capture by reference (if that was desired for whatever reasons).

for (int i = 0; i < 2; i++)
{
  foos.push_back([&i](int x) -> int
  {
    std::cout << i << std::endl;
    return i;
  });
}

What happens in C++ is very similar to what happens in C#. Here's some pseudo-code that shows one plausible way the compiler might implement this (simplified version):

class <lambda0> 
{ 
  int _i; 
  
public: 
  <lambda0>(int i) : _i(i) {} 
  
  int operator()(const int arg) 
  {
    std::cout << i << std::endl;
    return i;
  } 
}; 

If you look at the disassembly, you will see a call to the () operator where the lambda is executed, something like the following:

00CA20CB  call `anonymous namespace'::<lambda0>::operator() (0CA1415h)  

The const-ness of captured variables

C++ captures variables as const by default, whereas C# does not. Consider the following C# code.

int val = 10;
RunFoo(x =>
{
    val = 25;
    return x;
});

Now the syntactic equivalent C++ code follows.

int val = 10;
RunFoo([val](int x) -> int
{
  // val = 25; <-- will not compile
  return x;
});

To lose the const-ness of the captured variable, you need to explicitly use the mutable specification.

RunFoo([val](int x) mutable -> int
{
  val = 25;  // compiles
  return x;
});

C# does not have a syntactic way to make captured variables const. You'd need to capture a const variable.

Local assignment

In C#, you cannot assign a lambda to a var variable. The following line of code won't compile.

var f = x => x;

You'll get the following compiler errror.

// Cannot assign lambda expression to an implicitly-typed local variable	

VB.NET apparently supports it (via Dim which is their var equivalent). So it's a little strange that C# decided not to do that. VB.NET generates an anonymous delegate and uses Object for all the arguments (since deduction is not possible at compile time).

Consider the C++ code below.

auto func =  [](int x) { return x; };

Here func is now of the compiler-generated lambda type. You can also use the function<> class (although in this case it's not needed).

function<int(int)> copy = func;

When you directly invoke the lambda, the code will be something like:

0102220D  call `anonymous namespace'::<lambda0>::operator() (1021456h)  

When you call it via the function<> object, the unoptimized code will look like:

0102222B  call  std::tr1::_Function_impl1<int,int>::operator() (102111Dh) 
 - - - >
        010284DD  call std::tr1::_Callable_obj<`anonymous namespace'::<lambda0>,0>::_ApplyX<int,int &> (10215FAh)  
         - - - >
                0102B73C  call `anonymous namespace'::<lambda0>::operator() (1021456h)  

Of course, the compiler will trivially optimize this so the release mode binary code will be identical in both cases.

Calling methods from lambdas

The following example shows a method being called from a C# lambda.

void Do(int x) { }

void CallDo() 
{
    RunFoo(x =>
        {
            Do(x);
            return x;
        });
}

What the C# compiler does here is to generate a private instance method that calls the method defined in the lambda.

private int <LambdaMethod>(int x)
{
    this.Do(x);
    return x;
}

It's this method that's passed to RunFoo as a delegate. Now imagine that you are also capturing a variable in addition to calling a member method. The compiler now generates a class that captures the variable as well as the this reference.

private class <Lambda>
{
    public int t;
    public Program __this;
    
    public <Lambda>() {}
    
    public int <CallDo>(int x)
    {
        this.__this.Do(x + this.t);
        return x;
    }
}

This is a little more obvious in C++ because you have to explicitly capture the this pointer to call a member function from the lambda. Consider the example below.

int Do(int h)
{
  return h * 2;
}

void Test()
{
  auto func =  [this](int x) -> int
  { 
    int r = Do(1);
    return x + r; 
  };

  func(10);
}

Notice how this has been captured there. Now when the compiler-generated lambda-class's () operator is called, invoking the method is merely a matter of calling that function and passing the captured this pointer.

call  T::Do (1021069h)

Lambdas in C++/CLI

One big disappointment for C++//CLI developers (all 7 of them) is the fact that C++/CLI does not support managed lambdas. You can use lambdas in C++/CLI but they will be native, and so you won't be able to easily interop with managed code that expects for instance  a Func<> argument. You'd have to write plumbing classes to convert your native lambdas to managed delegates. An example is shown below.

class LambdaRunner
{
  function<int(int)> _lambda;

public:
  LambdaRunner(function<int(int)> lambda) : _lambda(lambda)
  {
  } 

  int Run(int n)
  {
      return _lambda(n);
  }
};

The above class is the native implementation of the lambda runner. The following class is the managed wrapper around it.

ref class RefLambdaRunner
{
  LambdaRunner* pLambdaRunner;

  int Run(int n)
  {
    return pLambdaRunner->Run(n);
  }

public:
  RefLambdaRunner(function<int(int)> lambda)
  {
    pLambdaRunner = new LambdaRunner(lambda);
  }

  Func<int, int>^ ToDelegate()
  {
    return gcnew Func<int, int>(this, &RefLambdaRunner::Run);
  }

  void Close()
  {
    delete pLambdaRunner;
  }
};

Using it would look something like the following.

auto lambda = [](int x) -> int { return x * 2; };
auto lambdaRunner = gcnew RefLambdaRunner(lambda);
int result  = lambdaRunner->ToDelegate()(10);
lambdaRunner->Close();

Well that's a lot of work to get that running smoothly. With some clever use of macros and template meta programming, you can simplify the code that generates the native and managed runner-classes. But it'll still be a kludge. So a friendly advice to anyone planning on doing this is - don't. Save yourself the pain.

Lambdas with WinRT and C++/CX

You can use lambdas in C++/CX with WinRT types.

auto r  = ref new R();
r->Go();

auto lambda = [r]()
{
};

// or

auto lambda = [&r]()
{
}

The dev-preview may have a subtle bug or two, but the expected behavior is that when you capture by copy you will incur AddRef and Release, whereas when you capture by reference, you will not. The compiler will try and optimize this away for you in copy-capture scenarios when it thinks it's safe to do so. And this may be the source of one of the bugs in the dev preview where a Release is optimized away but the AddRef is not resulting in a potential memory leak.   But it's a certainty that this will all be fixed by beta, so I wouldn't worry too much about it.

Performance worries

Performance is always an obsession with C++ developers (and some C# and VB developers too). So very often you find people asking in the forums if using lambdas will slow down their code. Well without optimization, yes, it will. There will be repeated calls to the () operator. But any recent compiler will inline that, so you will not have any performance drop at all when you use lambdas. In C#, you will not have compile time optimizations but the CLR JIT compiler should be able to optimize away the extra indirections in most scenarios. A side effect is that your binary will be a tad bulkier with all the compiler generated classes, but it's a very small price to pay for the powerful syntactic and semantic value offered by lambdas, in either C++ or in C#.

Conclusion

Please do submit feedback and criticism via the article forum below. All feedback and criticism will be carefully read, and tragically sad moments of silence will be observed for the more obnoxious responses. *grin*

History

  • November 3, 2011 - Article first published.
  • November 4, 2011
    • Minor typo and formatting fixes
    • Added section on calling methods from lambdas

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Nish Sivakumar
United States United States
Member
Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.
 
Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com.
 
Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy Summer Love and Some more Cricket as well as a programming book – Extending MFC applications with the .NET Framework.
 
Nish's latest book C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.
 
Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalmy 5memberMohammad A Rahman6 Dec '12 - 22:54 
Nice article.

GeneralMy vote of 5memberRafael Nicoletti19 Oct '12 - 14:40 
Very good and easy-to-read article.
Congratulations
GeneralMy vote of 5membermanoj kumar choubey29 Jun '12 - 7:31 
nice
AnswerRe: My vote of 5mvpNish Sivakumar8 Aug '12 - 2:51 
Thanks!
Regards,
Nish
My technology blog: voidnish.wordpress.com

GeneralMy vote of 5membertheanil28 Jan '12 - 8:54 
5
GeneralRe: My vote of 5mvpNishant Sivakumar28 Jan '12 - 11:06 
Thanks Anil.
Regards,
Nish
My technology blog: voidnish.wordpress.com

GeneralMy vote of 5mvpthatraja9 Jan '12 - 18:26 
Nice one, Looks like I forgot to vote here at that time but I did in competition. Cheers!
GeneralRe: My vote of 5mvpNishant Sivakumar28 Jan '12 - 11:06 
Thanks Raja!
Regards,
Nish
My technology blog: voidnish.wordpress.com

QuestionHow vs. whymemberDavidCrow3 Jan '12 - 4:40 
Maybe it was not in the scope of your article, but why would a person need or want to use a lamda?

"One man's wage rise is another man's price increase." - Harold Wilson

"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous


AnswerRe: How vs. whymvpNishant Sivakumar3 Jan '12 - 5:09 
Well for me personally, it's mostly syntactic convenience. In certain scenarios it also improves code readability, and helps me avoid creating a method merely because I am forced to. I also like the ability to capture local variables.
 
I’ve noticed that sometimes people tend to overuse them, and even use them in ways that result in code duplication. But that’s a lack of skill there rather than a problem with lambdas. There may also be specific scenarios where performance matters so much that that one extra clock cycle has to be avoided. Those are edge cases that affect a minority of programmers who are usually skilled enough to understand what needs to be done. Also in most cases the compiler generates identical code with or without lambdas.
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralMy vote of 5membertecgoblin2 Jan '12 - 20:02 
I still prefer the c# syntax (more readable for most real-life scenarii), but you have some very interesting details here!
GeneralRe: My vote of 5mvpNishant Sivakumar3 Jan '12 - 5:10 
Thank you.
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralMy vote of 5memberClemente Giorio19 Dec '11 - 10:15 
It's helpful
GeneralRe: My vote of 5mvpNishant Sivakumar2 Jan '12 - 4:05 
Thank you.
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralMy vote of 5mvpMd. Marufuzzaman16 Dec '11 - 20:06 
really helpful...
GeneralRe: My vote of 5mvpNishant Sivakumar2 Jan '12 - 4:05 
Thanks!
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

Questionvery nicememberCIDev14 Dec '11 - 7:17 
A well written and useful article; 5 from me. Smile | :)
Just because the code works, it doesn't mean that it is good code.

AnswerRe: very nicemvpNishant Sivakumar14 Dec '11 - 7:30 
Thank you!
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralMy vote of 5mvpAbhinav S13 Dec '11 - 18:23 
Nice article.
GeneralRe: My vote of 5mvpNishant Sivakumar14 Dec '11 - 4:33 
Thank you!
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralMy vote of 5memberKjellKod.cc13 Dec '11 - 5:38 
Excellent comparison! and it looks like you'll get the best article vote on November. Good Job Nishant!
 
Keep 'em articles coming
GeneralRe: My vote of 5mvpNishant Sivakumar14 Dec '11 - 4:34 
Thanks Smile | :)
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

Generalgood onememberNandaKumer8 Dec '11 - 17:06 
good one Nish and you deserve 5.
--NDK
SuggestionSome thoughts... [modified]memberMember 447522515 Nov '11 - 15:43 
It is unlikely that C++ will support type-deduction in lambda arguments though.
 
This is simply untrue – why you assume so? Polymorphic lambdas are quite likely to be added in the future, they didn't make it for C++11 for the reason explained by Dave Abrahams, a member of the ISO C++ committee:
 
Contrary to reports elsewhere, there’s an honest-to-goodness technical reason that we don’t have them: nobody could figure out how to integrate polymorphic lambdas with concepts (see section 5.1 of N1968), which were at the time to be a flagship feature of C++11. But, but, but… concepts didn’t make it into C++11, so surely we can have our polymorphic lambdas, now? Not so fast. There are still a lot of people who want the concepts feature, and none of us want to add anything to the language that might be incompatible with concepts. (See here for more.)
 
So they postponed polymorphic lambdas to reduce the risk of incompatibility with another expected but still incomplete feature – concepts.
 
Then you write:
 
Now take a look at similar C++ code.
for each(auto foo in foos)
This is not C++, it's C++/CLI. The proper C++ would be:
for(auto foo : foos)
Also, no reason to pass foo by value.
 
It would be also nice to mention the capture-all syntax ([&], [=]) and mixed capture syntax ([&, i], [=, &i]).
 
The C++/CLI example is overcomplicated. You don't need the LambdaRunner class at all, in RefLambdaRunner you may just use std::function instead. Close() method? Come on, this is not C# - use a destructor. And ToDelegate() would be more convenient as a free (non-member function), or even better – a conversion operator. Also, it's easy to make RefLambdaRunner at least a bit more universal by declaring it as a template (variadic templates would solve the problem completely for any number of arguments if only VC++ implemented them...) To sum up, the example could look like this:
template<typename Arg, typename Ret>
ref struct NativeFunc
{
  typedef std::function<Ret(Arg)> FunctionType;
 
  NativeFunc(const FunctionType & f) : Function(new FunctionType(f))
  {
  }
 
  !NativeFunc()
  {
    delete Function;
    Function = nullptr;
  }
 
  ~NativeFunc()
  {
    this->!NativeFunc();
  }
 
  Ret Run(Arg arg)
  {
    return (*Function)(arg);
  }
 
  operator Func<Arg, Ret>^ ()
  {
    return gcnew Func<Arg, Ret>(this, &NativeFunc::Run);
  }
 
private:
 
  const FunctionType * Function;
};
And to use it:
Func<int, int>^ func = gcnew NativeFunc<int, int>([] (int x) { return x * 2; });
int result = func(10);
The code is tested and working. Note that in the second to last line I create an object and don't dispose it – that's fine since GC will call the finalizer when the object is no longer needed and release the unmanaged memory. The NativeFunc class could also make use of perfect forwarding, but I wanted to keep it relatively simple.

modified 15 Nov '11 - 22:46.

GeneralRe: Some thoughts...mvpNishant Sivakumar15 Nov '11 - 16:41 
Thanks for the feedback. I appreciate it.
 
Member 4475225 wrote:
This is simply untrue – why you assume so? Polymorphic lambdas are quite likely
to be added in the future, they didn't make it for C++11 for the reason
explained by Dave Abrahams, a member of the ISO C++ committee:

 
I accept that. I should have worded it differently. But from a VC++ perspective, the feature is unlikely to make it in the next 2 versions (even that is optimistic).
 
Member 4475225 wrote:
So they postponed polymorphic lambdas to reduce the risk of incompatibility with
another expected but still incomplete feature – concepts.

 
Again, I agree. And once again my wording could have been better.
 
Member 4475225 wrote:
This is not C++, it's C++/CLI.

 
for each has been supported for native code since VC++ 2008. It's a VC++ specific compiler feature (and the syntax is identical to C++/CLI and C++/CX).
 
Member 4475225 wrote:
It would be also nice to mention the capture-all syntax ([&],
[=]) and mixed capture syntax ([&, i], [=,
&i]
).

 
Well, as noted at the beginning of the araticle, I did not mean this to comprehensively cover lambda usage, it was intended more as a compare/contrast. That said, from other feedback I got, I now think that I should perhaps have included more detail (and I may do so ina future update). So thanks for the suggestion.
 
Member 4475225 wrote:
The C++/CLI example is overcomplicated. You don't need the
LambdaRunner class at all, in RefLambdaRunner you may
just use std::function instead.

 
Agreed. Rather quickly done.
 
Member 4475225 wrote:
Close() method? Come on, this is not C# - use a destructor.

 
Well, I didn't want to implement the C++/CLI-dispose pattern for my example (distracting). And I also didn't want to depend on the GC (for the example). Just personal preference.
 
Member 4475225 wrote:
The code is tested and working. Note that in the second to last line I create an
object and don't dispose it – that's fine since GC will call the finalizer when
the object is no longer needed and release the unmanaged memory. The
NativeFunc class could also make use of perfect forwarding, but I
wanted to keep it relatively simple.

 
Nicely done! Very elegant too (given the limitations). Despite that, I still won't recommend that anyone try and use lambdas in C++/CLI code. The indirections required (via helper classes) make it a very kludgy approach.
 
And yeah, if we did have variadic templates, it'd have been a different story. Perhaps in 2 years time.
 
Thanks once again for your feedback.
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralRe: Some thoughts...memberRobKaw15 Nov '11 - 17:16 
for each has been supported for native code since VC++ 2008. It's a VC++ specific compiler feature (and the syntax is identical to C++/CLI and C++/CX).
 
OK, but that VC++ allows this extension for native code too doesn't negate the fact that it's not C++. My point is that saying "C++" implies "ISO C++", not "C++ with some vendor-specific extensions". Well, maybe I'm a bit nitpicky at that. I just don't like calling non-standard extensions like this as "C++", especially when the standard way of doing that is different. Poke tongue | ;-P
 
Nicely done! Very elegant too (given the limitations).
 
Thanks, feel free to use the code if you wish.
 
Despite that, I still won't recommend that anyone try and use lambdas in C++/CLI code. The indirections required (via helper classes) make it a very kludgy approach.
 
I feel this is too strong recommendation. Especially with small utility write-once use-everywhere classes like the one I've written I don't see much burden nor danger in combining lambdas and delegates.
 
BTW, I've made a small correction to the code (C++/CLI allows destructors to be called more than once).
GeneralMy vote of 5memberahmed zahmed14 Nov '11 - 8:30 
Very nice article! Well organized comparison between languages.
GeneralRe: My vote of 5mvpNishant Sivakumar15 Nov '11 - 7:04 
Thank you!
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

QuestionTypo?adminChris Maunder13 Nov '11 - 23:37 
"where the return type will be deducted"
 
Do you mean:
 
"where the return type will be deduced"?
cheers,
Chris Maunder
 
The Code Project | Co-founder
Microsoft C++ MVP

AnswerRe: Typo?mvpNishant Sivakumar14 Nov '11 - 1:46 
Oops D'Oh! | :doh:
 
Yes, the return type is deduced, it's certainly not deducted. Blush | :O
 
Thanks Chris. Will fix this (and the other typo someone reported) today.
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralMy vote of 3memberPetro Protsyk9 Nov '11 - 5:41 
Nothing was said about expression trees, constructing lambdas from expression trees.
GeneralRe: My vote of 3mvpNishant Sivakumar14 Nov '11 - 5:13 
Petro Protsyk wrote:
Nothing was said about expression trees,
constructing lambdas from expression trees.

Thanks Petro, but expression trees are really a bit of a C# artifact (in the lambda context). It's not really an absolute part of the use or implementation of lambdas and does not have an equivalent in standard C++ (not considering 3rd party libs like boost). That's why there's no mention of it in the article.
 
If I do a non-trivial update, I will probably add a section on that as well.
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralC++ AMPmemberKen Domino7 Nov '11 - 10:15 
I think the utility of lambda functions shines when writing kernels in the C++ AMP extension, something that you haven't mentioned. CUDA and OpenCL, two extensions to C++ to program GPUs, force the programmer to abstract kernels into functions that are completely separated from the code that calls it. In some situations, that's OK. But other times, it's really unnecessary. In a way, it would be similar to forcing programmers to write the body of a for-loop into a function, so you couldn't say "for (int i=0; i < N; ++i) { data[i] = 0.0; ...}". With lambdas, it's now easier to program the GPU given a PRAM algorithm.
GeneralRe: C++ AMPmvpNishant Sivakumar14 Nov '11 - 5:10 
Thanks Ken. I had not thought of that at all. If I do a non-trivial update, I will probably mention that too.
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralMy vote of 5memberbartolo7 Nov '11 - 10:08 
Very useful, thanks! I will be checking out your book even though I am not in that exclusive group of 7 Smile | :)
GeneralRe: My vote of 5mvpNishant Sivakumar14 Nov '11 - 5:09 
bartolo wrote:
Very useful, thanks! I will be checking out your
book even though I am not in that exclusive group of 7 Smile | :)

Heh Smile | :)
 
Thanks!
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralRe: My vote of 5groupNorm .net17 Nov '11 - 23:04 
A lot of work to write a book for 7 sales Nish Wink | ;)
Software Kinetics Wear a hard hat it's under construction

Metro RSS
 


GeneralRe: My vote of 5mvpNishant Sivakumar18 Nov '11 - 2:02 
Heh Smile | :)
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralRe: My vote of 5groupNorm .net18 Nov '11 - 6:34 
You never know with the advent of WinRT, C++ and C++/CLI may be back in fashion again.
Software Kinetics Wear a hard hat it's under construction

Metro RSS
 


GeneralRe: My vote of 5mvpNishant Sivakumar18 Nov '11 - 6:36 
Norm .net wrote:
You never know with the advent of WinRT, C++ and C++/CLI may be back in fashion
again.

C++/CX rather (similar syntax but native). Yeah, I do think so too Smile | :)
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralRe: My vote of 5groupNorm .net18 Nov '11 - 6:50 
Better dust off my C++ skills, I haven't touch C++ for over 6 years, I've been following the gossip on WinRT and it seems C++ coder maybe be treated as 1st class citizens in the world of Win8.
Software Kinetics Wear a hard hat it's under construction

Metro RSS
 


GeneralMy vote of 5mvpLuc Pattyn7 Nov '11 - 9:32 
Very interesting. I'll have to read it again.
 
I do have two suggestions:
 
1. please mention which version of .NET and Visual Studio is required for this to work.
2. the article would be more browseable when the C# and C++/CLI snippets had different background colors; my tip Using PRE tags on Code Project[^] shows a way to get that.
 
Smile | :)
GeneralRe: My vote of 5memberGarth J Lancaster8 Nov '11 - 12:01 
Luc Pattyn wrote:
please mention which version of .NET and Visual Studio is required for this to
work.

 
good call Luc - I was going to ask Nishant to provide a such a table - eg, what lamda 'support'/functionality is available in C# 2.0, 3.5, 4 etc
 
'g'
GeneralRe: My vote of 5mvpLuc Pattyn8 Nov '11 - 12:50 
I looked it up, LINQ and lambdas require .NET >= 3.5
Not sure whether they evolved from 3.5 to 4.0
 
Smile | :)
Luc Pattyn [My Articles] Nil Volentibus Arduum

GeneralRe: My vote of 5memberGarth J Lancaster8 Nov '11 - 12:57 
thanks
 
yes, I did a little digging myself, the closest I could come in .Net 2.0 was 'anonymous expressions', and a couple of references to go into further
 
http://stackoverflow.com/questions/208381/whats-the-difference-between-anonymous-methods-c-2-0-and-lambda-expressions[^]
 
Lambda Expressions and Expression Trees: An Introduction[^]
 
'g'
AnswerRe: My vote of 5mvpLuc Pattyn12 Nov '11 - 3:30 
Thanks. I like the CP article by J. Dunlap.
 
A small warning: lambda expressions require C#3.0 or above, which in turn means .NET 3.5 or above (and not 3.0!).
 
Smile | :)
Luc Pattyn [My Articles] Nil Volentibus Arduum

GeneralRe: My vote of 5mvpNishant Sivakumar14 Nov '11 - 5:21 
Luc Pattyn wrote:
A small warning: lambda expressions require C#3.0 or above, which in turn means
.NET 3.5 or above (and not 3.0!).
 

The 3.0 in C# 3.0 refers to the C# compiler/language version while the 3.5 in .NET 3.5 refers to the framework version (which actually uses .NET CLR 2.0)! Kinda confusing I guess.
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralRe: My vote of 5mvpLuc Pattyn14 Nov '11 - 5:33 
Very confusing indeed, IMO they should have called the .NET versions 1.x, 2.0, 2.5 (instead of 3.0), 3.0 (instead of 3.5), 4.0 ...
 
Smile | :)
Luc Pattyn [My Articles] Nil Volentibus Arduum

GeneralRe: My vote of 5mvpNishant Sivakumar14 Nov '11 - 5:36 
Well there are 4 entities at play here with their own versioning. You have C# language versions, different from .NET framework versions, different from CLR versions (.NET 2, 3, 3.5 all run on the 2.0 CLR), and then you also have Visual Studio versions. I mentally associate stuff with VS versions and target OSes since the other versions don't really affect me as much as my dev environment and what OSes I can deploy my apps in.
Regards,
Nish
My technology blog: voidnish.wordpress.com
 
You've gotta read this : Using lambdas - C++ vs. C# vs. C++/CX vs. C++/CLI

GeneralRe: My vote of 5mvpLuc Pattyn14 Nov '11 - 5:45 
Yes, however the C# (and other) compilers come with .NET, so they really should share their major/minor version numbers. And I always refer to .NET versions, not VS versions, as VS is just a tool, which you could do without, and it allows targetting different .NET versions anyway (I mostly use VS2008 and target .NET 2.0!).
 
FWIW: I have this article[^] which I try and keep up-to-date (ignoring beta stuff). I hope it is all correct.
 
Smile | :)
Luc Pattyn [My Articles] Nil Volentibus Arduum

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 4 Nov 2011
Article Copyright 2011 by Nish Sivakumar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid