The Visual C++ compiler in the Microsoft Visual Studio 2010 September Community Technology Preview (CTP) contains support for four C++0x language features, namely lambdas, auto, static_assert, and rvalue references. Today, I’m going to explain the first three features in detail. (And I’m going to dedicate an entire post to explaining rvalue references in the near future, simply because explaining them now would double the length of this already very long post.)
First, a few quick things:
1. Today’s post is brought to you by Stephan T. Lavavej, Visual C++ Libraries Developer, and the letters C, A, and T. Note that as a libraries dev, I didn’t implement these features. That was the work of Jonathan Caves, front-end compiler dev, voting Standardization Committee member, and all-around ninja.
2. I refer to the Visual C++ compiler in VS 2010 as VC10 (VS 2008 contained VC9, VS 2005 contained VC8, etc. – 10 is not short for 2010).
3. C++0x refers to the upcoming C++ Standard, which is still being drafted. (The Standardization Committee hopes that they’ll be finished in 2009, making it C++09; the joke is that if it slips to 2010 or later, the ‘x’ will be hexadecimal.) C++98 and C++03 refer to the current C++ Standard. (Without going into a history lecture here, the 2003 C++ Standard was merely a “service pack” for the original 1998 C++ Standard, and most people can disregard the differences. C++03 and C++0x are totally different, despite appearances.)
4. I’d like to thank the Standardization Committee for developing these wonderfully useful and well-crafted features. They also make important documents available on their website:
C++0x language feature status: http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2705.html
C++0x library feature status: http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2706.html
C++0x Working Draft: http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2798.pdf
5. There are always bugs (although hopefully not too many), which is the whole point of the CTP. Please report bugs to us via Microsoft Connect.
Now, let’s look at the features!
lambdas
In C++0x, “lambda expressions” implicitly define and construct unnamed function objects, which then behave like handwritten function objects. This is the “Hello, World” lambda:
C:Temp>type meow.cpp
#include <algorithm>
#include <iostream>
#include <ostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
}
for_each(v.begin(), v.end(), [](int n) { cout << n << ” “; });
cout << endl;
}
C:Temp>cl /EHsc /nologo /W4 meow.cpp > NUL && meow
0 1 2 3 4 5 6 7 8 9
The [] is the lambda-introducer, which tells the compiler that a lambda expression is beginning. The (int n) is the lambda-parameter-declaration, which tells the compiler what the unnamed function object class’s function call operator should take. Finally, the { cout << n << ” “; } is the compound-statement which serves as the body of the unnamed function object class’s function call operator. By default, the unnamed function object class’s function call operator returns void.
So, C++0x has mentally translated this into what you’d write in C++98:
C:Temp>type meow98.cpp
#include <algorithm>
#include <iostream>
#include <ostream>
#include <vector>
using namespace std;
struct LambdaFunctor {
void operator()(int n) const {
cout << n << ” “;
}
};
int main() {
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
}
for_each(v.begin(), v.end(), LambdaFunctor());
cout << endl;
}
C:Temp>cl /EHsc /nologo /W4 meow98.cpp > NUL && meow98
0 1 2 3 4 5 6 7 8 9
Now I’m going to stop saying things like “the unnamed function object class’s function call operator returns void” and start saying “the lambda returns void“, but it’s important to remember what lambda expressions are doing: defining classes and constructing objects.
Of course, the compound-statement of a lambda can contain multiple statements:
C:Temp>type multimeow.cpp
#include <algorithm>
#include <iostream>
#include <ostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
}
for_each(v.begin(), v.end(), [](int n) {
cout << n;
if (n % 2 == 0) {
cout << ” even “;
} else {
cout << ” odd “;
}
});
cout << endl;
}
C:Temp>cl /EHsc /nologo /W4 multimeow.cpp > NUL && multimeow
0 even 1 odd 2 even 3 odd 4 even 5 odd 6 even 7 odd 8 even 9 odd
Now, lambdas don’t always have to return void. If a lambda’s compound-statement is { return expression; } , then the lambda’s return type will be automatically deduced to be the type of expression:
C:Temp>type cubicmeow.cpp
#include <algorithm>
#include <deque>
#include <iostream>
#include <iterator>
#include <ostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
}
deque<int> d;
transform(v.begin(), v.end(), front_inserter(d), [](int n) { return n * n * n; });
for_each(d.begin(), d.end(), [](int n) { cout << n << ” “; });
cout << endl;
}
C:Temp>cl /EHsc /nologo /W4 cubicmeow.cpp > NUL && cubicmeow
729 512 343 216 125 64 27 8 1 0
Here, the type of n * n * n is int, so this lambda’s function call operator returns int.
Lambdas with more complicated compound-statements don’t get automatically deduced return types. You have to explicitly specify them:
C:Temp>type returnmeow.cpp
#include <algorithm>
#include <deque>
#include <iostream>
#include <iterator>
#include <ostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
}
deque<double> d;
transform(v.begin(), v.end(), front_inserter(d), [](int n) -> double {
if (n % 2 == 0) {
return n * n * n;
} else {
return n / 2.0;
}
});
for_each(d.begin(), d.end(), [](double x) { cout << x << ” “; });
cout << endl;
}
C:Temp>cl /EHsc /nologo /W4 returnmeow.cpp > NUL && returnmeow
4.5 512 3.5 216 2.5 64 1.5 8 0.5 0
The -> double is the optional lambda-return-type-clause. Why doesn’t it go on the left, like what programmers have been doing with C functions for longer than I’ve been alive? Because then the lambda-introducer wouldn’t come first, and that’s what tells the compiler that a lambda expression is beginning. (Figuring out this kind of stuff is what the Core Working Group excels at; trying to imagine whether a given construct would be parseable within C++ hurts my head.)
If you forget the lambda-return-type-clause, the compiler will complain

PingBack from http://blog.a-foton.ru/index.php/2008/10/28/lambdas-auto-and-static_assert-c0x-features-in-vc10-part-1/
Regarding lambdas – I see that you didn’t implement the part about std::reference_closure yet. Are you planning to do it?
Also, I recall that there was an shortcut expression syntax for lambdas at some point: [](int x)(x + 1) instead of [](int x) { return x + 1 } – or something along these lines. Was it dropped from the spec?
[int19h]
> Regarding lambdas – I see that you didn’t implement the part about std::reference_closure yet.
Correct.
> Are you planning to do it?
Not in VC10. std::reference_closure implies and requires a certain optimization (the "static scope pointer" mentioned by WP N2798) that must be supported by the compiler back-end.
> Also, I recall that there was an shortcut expression syntax for lambdas at some point
As of WP N2798 (the latest Working Paper), lambda bodies are ordinary compound-statements.
Lambda syntax was in flux during development, as usual. This appears to have changed between proposals N2529 and N2550.
Very good posting. I’m looking forward to see auto keyword upcoming new compiler.
However, I have a question. Is there any plan for Microsoft to support C99 such as variable-length array, C++-like variable declaration, and restrict keyword? In Windows platform, in order to use C99, I am forced to use another compiler like Intel C/C++ compiler.
Nice job for C++. But, I really hope C99 will be implemented in the new MSVC compiler.
My latest in a series of the weekly, or more often, summary of interesting links I come across related to Visual Studio. Codart has released devefor , an extension to Visual Studio that helps you monitor your development process. Greg Duncan posted a
This is very good news. In recent years, as a user of various template libraries, the two things that I have missed the most in C++ are lambdas and the auto keyword. I am happy to see that I will have these at my disposal soon, but also very much hope that Concepts make it into the final release. This is the third big thing missing from today’s C++ that would make writing (and using) more advanced template classes less like brain surgery on a rocket scientist (in orbit, with one arm tied to your back).
Keep it up!
[David]
> also very much hope that Concepts make it into the final release.
Concepts will be super duper awesome. However, they will not be implemented in VC10. Concepts are C++0x’s biggest feature, and they were just recently finalized and integrated into the Working Paper (i.e. long after VC10’s development started).
Hey, Stephan! It’s good to read your posts, as always.
That was an outstanding introduction to lambda expressions in C++0x. I especially appreciated the extensive side-by-side comparisons of the lambda examples and their ordinary functor equivalents (except for the default capture examples, which were conspicuous by the absence of "mentrally translated to" counterparts. Was that intentional?)
I can’t say I’m fond of the syntax, but I’ll admit that it beats "cout << _1"….
Hey, Stephan! It’s good to read your posts, as always.
That was an outstanding introduction to lambda expressions in C++0x. I especially appreciated the extensive side-by-side comparisons of the lambda examples and their ordinary functor equivalents (except for the default capture examples, which were conspicuous by the absence of "mentally translated to" counterparts. Was that intentional?)
I can’t say I’m fond of the syntax, but I’ll admit that it beats "cout << _1"….
[Uche Akotaobi]
> except for the default capture examples, which were conspicuous by the absence of "mentrally translated to" counterparts. Was that intentional?
Default captures are mentally translated into explicit captures. For example, defaultcapturekittybyvalue.cpp is mentally translated into capturekittybyvalue.cpp, which is then mentally translated into capturekittybyvalue98.cpp. Those examples were otherwise identical in order to demonstrate this.
[Stephan]
> Default captures are mentally translated into explicit captures.
Ah, okay. That makes sense.
Sorry for the double post.
A few more questions regarding your plans here:
1) Are you going to implement the "range-based for-loop" (N2778 at the moment)? This doesn’t work, currently:
std::vector<int> v;
for (int x : v) { … }
I understand that, given lambdas, I should just use std::for_each, but still… given that you pretty much have it implemented already as "for each", it would be a fairly simple change to the syntax, no?
2) Will nullptr take on its C++0x semantics, complete with nullptr_t? (didn’t have time to check this on the CTP, unfortunately)
3) As I understand, you’ll be moving all the stuff from TR1 that makes reappearance in C++0x into namespace std. What about the new stuff, such as std::unique_ptr?
> Concepts will be super duper awesome. However, they will not be implemented in VC10.
Okay, it’s better to have that confirmed so I can focus on what *will* be in. VC has become so much better at implementing stadards – and doing it fast – that I am still happy. For us still doing significant C++ work, a compliant compiler and a powerful project/build system, are top priorities, so it’s good to see investments in those areas in VC10.
I am still a bit surprised and slightly disappointed at the continued focus on crufty old MFC, when you could have made the more modern WTL a first class member of VC10. Imagine, an evolved WTL with less of an "impedance mismatch" against STL, using the latest C++0x features, and a touch of Boost (a la the recent adoption of jQuery inside of VS). Here’s hoping…
Will VC10 support extern templates?
Shame other features like concepts didn’t make it, but I can see why.
Two questions then:
1: These are the 0x core language features that’ll make it in. How about library changes? (And how about the new unicode char types?)
2: Can we expect to see more 0x support added over VC10’s lifetime, through servicepacks and such?
I’m just hoping we won’t see another 10-year span between the release of the standard, and reasonably-conforming compilers.
A kind of a "personal curiosity" question here: are the newly supported C++0x features used internally in the upcoming Microsoft products? I understand that it’s probably not the right place to ask such a general question – and you might not know whether, e.g. the Windows and Office teams (which, I would imagine, are two biggest C++ users in Microsoft) use them. But do you use them in the C++ compiler itself, for example, and/or in the libraries?
Stephan, thanks for the heads-up. Looking forward to all the tasty deliciousness of VC10!
I want it now! I want it now! Alas, probably won’t be able to adopt C++0x-isms for my project for two more cycles (4 years). Engineering bureaucracy. :-(
Kudos to the VC10 team (and expecting even more C++0x implementation goodness for VC11, of course), and to the JTC1/SC22/WG21 folks.
@int19h: I don’t think any of the C++0x features will be used in the coming product wave. Those features are not yet stable for production use and developers also first needs to get used to it.
Or how Steven Sinofsky said it:
"We’re building a class library, not a compiler test suite, so there is no need to try to use all the features of C++."
http://blogs.msdn.com/techtalk/archive/2005/08/18/453492.aspx
> C++0x Working Draft:
> http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2798.pdf
It looks like C++ 2003. I have’t found any 0x improvements there.
> It looks like C++ 2003. I have’t found any 0x improvements there.
You have to look more attentively :) New additions are marked with cyan, removals are in striked-out red. For a few new things to look at – 5.1.1 is about lambdas; 6.5.4, range-based for-statement; 7.6, attributes; 14.9-10, concepts.
> int19h: I don’t think any of the C++0x features will be used in the coming product wave. Those features are not yet stable for production use and developers also first needs to get used to it.
Well, you can’t avoid lambdas when using PPL – or are you saying that you guys aren’t using PPL internally, either? What about "eating our own dog food"?
Or are you saying that it’s not yet stable at this specific moment, but will be sufficiently stable for internal use some time before VC10 is released?
Personally, I would feel more comfortable using the release version of VC10 and PPL knowing that it was used by someone else to build successful production apps before me ;)
@int16h: I’m not affiliated with Microsoft, all MS employees have a [MSFT] behind their name.
I also haven’t looked at the Parallel Pattern Library yet.
But Windows 7 will definitely not be build with the VC10 compiler, so no C++0x features. I’m not sure if they use the VC8 or VC9 compiler, I guess they’ve switched to the VC9 one. Maybe someone from the VC team can shed some light on it. I haven’t seen the Win7 SDK yet.
[int19h]
> 1) Are you going to implement the "range-based for-loop"
The range-based for statement is powered by concepts (see N2798 6.5.4 [stmt.ranged]), so it won’t be implemented in VC10.
> given that you pretty much have it implemented already as "for each", it would be a fairly simple change to the syntax, no?
The "for each" extension is highly limited; it calls .begin() and .end() (so it’ll work with tr1::unordered_foo), but it’s not customizable like the range-based for statement.
> 2) Will nullptr take on its C++0x semantics, complete with nullptr_t?
nullptr won’t be implemented in VC10.
> 3) As I understand, you’ll be moving all the stuff from TR1 that makes reappearance in C++0x into namespace std.
We’re dragging TR1 components into namespace std with using-declarations.
> What about the new stuff, such as std::unique_ptr?
We’re implementing some C++0x library features in VC10. I can confirm that unique_ptr and forward_list are being implemented. (Note that they’ve been checked into my branch, but they’re not in the CTP. The CTP doesn’t contain any C++ Standard Library changes.)
[David]
> VC has become so much better at implementing stadards – and doing it fast – that I am still happy.
Glad to hear it!
[Nikola Smiljanic]
> Will VC10 support extern templates?
No.
[Jalf]
> Shame other features like concepts didn’t make it, but I can see why.
Concepts were simply never on the table.
> 1: These are the 0x core language features that’ll make it in. How about library changes?
This is my area. We’re currently working on rewriting our Standard Library implementation for improved performance and C++0x conformance. For example, support for rvalue references is being added to our Standard Library implementation, which will trigger dramatic performance improvements in certain scenarios (and which will supersede VC8-9’s limited and fragile Swaptimization). We’re also picking up some new C++0x libraries, such as the aforementioned unique_ptr and forward_list (and my personal favorite, make_shared<T>()).
> (And how about the new unicode char types?)
That’s a language feature, which won’t be implemented in VC10.
> 2: Can we expect to see more 0x support added over VC10’s lifetime, through servicepacks and such?
Magic 8 Ball says: Cannot predict now.
[int19h]
> are the newly supported C++0x features used internally in the upcoming Microsoft products?
The limiting factor is how fast other teams can pick up the new compiler. VS itself is the first user, as the new compiler makes its way into all of our development branches. It takes longer for teams outside DevDiv, such as Windows and Office, to pick up the new compiler – also, they ship at different times, and are understandably loathe to pick up new toolchains late in their development cycles.
> But do you use them in the C++ compiler itself
JonCaves would know for sure, but this is my understanding: currently we don’t, because of how our build system works. Our compiler builds itself, of course, but we start with a checked-in "Last Known Good" (or LKG) compiler. As the name implies, this a build which is known to behave reasonably. The LKG compiler is used to build the new "phase 0" compiler, and then the phase 0 compiler is used to build itself, producing the phase 1 compiler. If that happens without anything being mangled horribly, the compiler can compile itself and we’re looking good. Periodically, the LKG build is updated, which is when new compiler features become available. (Due to how our build system works, the LKG compiler, and not the phase 1 compiler, is used to build the rest of VS.) After the next LKG update, the compiler itself (and anything else within VS, etc.) will be able to use rvalue references and other features unconditionally.
> and/or in the libraries?
Yes, although we currently guard uses of rvalue references with preprocessor machinery that detects whether we’re being compiled with the LKG compiler or the rvalue reference-aware compiler. These guards will be removed after the next LKG update, which is when we can really start having some fun.
[Andre]
> Those features are not yet stable for production use
Actually, they are quite stable. (There was an epic bug in template argument deduction that broke perfect forwarding with rvalue references, but it was found and fixed in time for the CTP.) If you find otherwise, prove me wrong by filing Microsoft Connect bugs! :-)
Thank you very much for detailed replies, Stephan!
> VS itself is the first user, as the new compiler makes its way into all of our development branches.
if VS uses the new features (now or soon), that’s certainly good enough for me to sleep well ;)
> We’re dragging TR1 components into namespace std with using-declarations.
Erm… I might be wrong, but isn’t it going to Break Things (for template specialization purposes etc), unless you have "strong using" implemented, and are using it for that purpose?
> If you find otherwise, prove me wrong by filing Microsoft Connect bugs! :-)
Personally, I’m probably going to wait until there is a non-VPC CTP release before seriously playing with the new stuff. VPC is just too slow and inconvenient for me to deal with – it’s good enough to quickly look at the new features, but experimenting is a pain.
Then again, mmm, lambdas… I might just have to endure :)
@Stephan: I wasn’t saying that the current CTP is buggy, but I doubt that Win7 will be build with a compiler from the development branch ;)
Does the Windows devision use publicly released versions? How do they decide up to which label (LKG ?) they branch? Do they integrate only selected changelists thereafter? How is the workflow if someone from the Windows team finds a bug in the compiler? I doubt they make fixes on their own in their branch but have to report them to get them fixed?
What do lambda expressions add to C++ besides making advanced use of the language even more difficult for humans to parse? If I were in charge of a progamming group, I’d probably force people to use named functions to preserve readability.
@Sniffy,
for small functors lambdas *are* more readable. Compare the "cout << n" sample where a lambda expression is used to the explicitly given struct LambdaFunctor with operator() overloaded. While reading the for_each line you have to lookup LamdaFunctor to see what kind of functor is called and what it does. The "inline" lambda lets you read everything in one place.
—
SvenC
@SvenC: I see the same problem with lambdas as with delegates in C#, code clustered through the whole app at places where it doesn’t belong. But unlike delegates I don’t think lambdas promote "unstructured" programming.
But I think it will take a while before lambdas are well used. If I compare code written in the 90s with todays code there is a huge different, and so it will be with lambdas in the next years.
The auto keyword is very useful for iterators, but I have the fear that novice users will use it the VB way :-<
[int19h]
> Erm… I might be wrong, but isn’t it going to Break Things (for template specialization purposes etc)
That’s a good question. I’ll ask.
[Andre]
> Does the Windows devision use publicly released versions?
I don’t know very much about this (from where I’m sitting, Windows is in a galaxy far, far away, on the other side of the street), but they’ve definitely used hotfixed versions in the past.
> How is the workflow if someone from the Windows team finds a bug in the compiler?
> I doubt they make fixes on their own in their branch but have to report them to get them fixed?
I believe that they request hotfixes from us.
[SvenC]
> for small functors lambdas *are* more readable.
Correct.
Note that all of my lambdas aren’t equally realistic; meow.cpp’s [](int n) { cout << n << " "; } , cubicmeow.cpp’s [](int n) { return n * n * n; } , and capturekittybyvalue.cpp’s [x, y](int n) { return x < n && n < y; } are very realistic (the last one is a very compelling use for captures, I was rather pleased with it), but overridekitty.cpp’s [=, &sum, &product](int& r) mutable { … } is obviously a desperate attempt to demonstrate mixed value and reference captures (there *are* uses for this in real programs; distilling it down to a small example is difficult).
If you inspect other languages with closures (Standard ML, Haskell, Common Lisp, Ruby, Smalltalk … whatever), you’ll see that closures are a very integral and most of all SIMPLE thing to use. The feature you presented above is more or less the opposite of that.
This new C++ standard has about as much reality as the new Fortran 2003 standard. C++ outlived its usefulness for application development.
As far as I understand, NRVO cannot deal with multiple return paths for multiple named objects et al, and move semantics should make this less of an issue because you can invoke the move constructor anyway. But I’m seeing some confusing results with the CTP when combining move semantics with "regular" RVO.
This invokes the move constructor (in a debug build without NRVO):
struct foo
{
foo() { std::cout << "foo()n"; }
foo(const foo&) { std::cout << "foo(const foo&)n"; }
foo(foo&&) { std::cout << "foo(foo&&)n"; }
};
foo test()
{
foo f; // avoid RVO
return f;
}
…
foo f = test();
This also invokes the move constructor for both true/false:
foo test(bool bar)
{
if (!bar)
{
foo f;
return f;
}
foo g;
return g;
}
…
foo f = test(true);
This, however, uses RVO for return foo(), but copy-constructs f to the caller:
foo test(bool bar)
{
if (!bar)
return foo();
foo f;
return f;
}
…
foo f = test(true);
If the compiler decides that it cannot determine RVO, shouldn’t it just treat the return path as returning a rvalue that can be move-constructed in the caller by default?
Furthermore, explicitly stating that the return type is an rvalue works as I would expect:
foo test(bool bar)
{
if (!bar)
return std::move(foo());
foo f;
return std::move(f);
}
Is this intended behavior or a compiler oversight? Or am I just way off? :)
The four features you have included are fantastic additions (well, at least three of them :)). However, I am slightly disappointed that decltype is not mentioned. Is it not going to be implemented in VC10? If so, why?
Tor Brede:
It is also my understanding that the move constructor should be invoked in the case of foo(true).
Don’t auto and typeof (and decltype) go hand in hand? I’ve written a large codebase which uses gcc’s typeof throughout, and have been hoping and waiting for years now for MSVC to support typeof. gcc’s had typeof forever. I don’t use MSVC for the single reason of lack of typeof. When I saw that this CTP was out, I was quite excited as I thought auto surely implies typeof. Apparently not.. but why?
http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10
Well, I can kind of see why, but I think missing Concepts means that you have no real C++/0x support – that’s the single most important new feature.
Once again us C++ developers are feeling like second class citizens. Maybe it’s time to jump ship…
@VC++ team – I hope those comments about "us C++ devs feeling second class … because you don’t give us xyz" don’t hurt you too much. That is so ungrateful of "those" C++ devs to get new features with every new VC++ version and still the only thing they do is moaning around about "the single most important feature missing".
@robthablob: whatever you do for others, are you sure that you always give everything in one shot to everybody wanting something from you? Yes? Well then, go on throwing stones.
—
SvenC
I’d like to answer robthablob.
Concepts were added to the C++ Working Paper at the very end of the last C++ Standards meeting (which was in July in San Francisco) just before the Working Paper was approved as the first Committee Draft. Before this point Concepts were a "potential" C++-0x feature, now they are, finally, an official C++-0x feature. Concepts are also by far and away the biggest C++-0x feature: my conservative estimate is that it would take me at least 1 year to implement the feature. So there is no way we csould have Concepts ready for Dev10 – there just isn’t the time.
This makes me very excited for C++0x! Lambda’s going to be pretty awesome.
If I was going to make one complaint it would be that lambda’s syntax isn’t going to be nice to remember at first. That’s one thing about Java that is nice: the syntax is easy, it just feels right. I’d still take C++ for the power any day.
[Nikola Smiljanic]
> Will VC10 support extern templates?
Actually, my previous answer was bogus. JonCaves informed me that extern templates have been implemented as an extension since Visual C++ 2.0. Like long long, this was a very popular extension (GCC implemented it too), so C++0x is Standardizing it.
[Julian St.]
> If you inspect other languages with closures (Standard ML, Haskell, Common Lisp, Ruby, Smalltalk … whatever),
> you’ll see that closures are a very integral and most of all SIMPLE thing to use.
> The feature you presented above is more or less the opposite of that.
This is incorrect. I know Scheme, so I’ll use it as an example. Scheme’s (lambda (n) (* n n n)) and C++0x’s [](int n) { return n * n * n; } are equally simple, after you get past their syntactic flavoring. In fact, C++0x lambdas (and C++ functors in general) have the upper hand, as they make dealing with mutable state easy. Scheme doesn’t. I don’t know about other functional languages – this is not a general criticism – but Scheme in particular makes dealing with mutable state way too complicated. Scheme’s environment model is utterly incomprehensible, while everyone knows how C++ data members work.
> This new C++ standard has about as much reality as the new Fortran 2003 standard. C++ outlived its usefulness for application development.
If you want X, for X != C++, you know where to find it.
[decltype]
> I am slightly disappointed that decltype is not mentioned. Is it not going to be implemented in VC10? If so, why?
[Zola Enola]
> When I saw that this CTP was out, I was quite excited as I thought auto surely implies typeof. Apparently not.. but why?
Implementing auto doesn’t implement decltype (C++0x’s name for what was previously called typeof) for free.
Paraphrasing our libraries and compiler front-end program manager Damien Watkins, the CTP is only the first look at our VC10 functionality and there is definitely more to come. We understand that certain features "go together", and that adding complementary features is a good thing in general. As always, customer feedback is a vital resource in forming our plans.
[robthablob]
Adding to JonCaves’ reply:
> Once again us C++ developers are feeling like second class citizens.
Compared to whom? Other languages? They don’t have templates, much less concepts. Other compilers? They haven’t implemented concepts yet. According to my knowledge, there’s only one partial implementation, the highly experimental prototype ConceptGCC (and its own webpage says "The compiler is very, very slow and can be rather unstable.").
[Tor Brede Vekterli]
> Is this intended behavior or a compiler oversight?
This appears to be a bug, thanks for the report. I’ve filed it in our internal bug tracking system (ID 540754).
> We understand that certain features "go together", and that adding
> complementary features is a good thing in general. As always, customer
> feedback is a vital resource in forming our plans.
Then let me formally say that in my opinion, r-value references are only semi-useful without variadic templates (for perfect forwarding), and auto is only semi-useful without decltype. So here’s a +1 for variadic templates and decltype. ;-)
[Adam Merz]
> r-value references are only semi-useful without variadic templates (for perfect forwarding)
Take a look at the implementation of VC9 SP1’s <functional>. No one wants variadic templates more than I do. :-)
Tor Brede Vekterli: JonCaves has confirmed that you’ve found a bug. He’s already figured out the problem and the fix. Thanks again for reporting it!
> n fact, C++0x lambdas (and C++ functors in general) have the upper hand, as they make dealing with mutable state easy. Scheme doesn’t.
I don’t understand this one. You can just as well mutate variables in the parent scope of lambda in Scheme as you can in C++ – noone has banned "set!" yet.
Oh yes, I’ll second that request for variadic templates and decltype. If there would be a choice between those two and concepts (I understand that there isn’t, just theoretizing), I would certainly pick the first two. Concepts are cool, but static_assert is "good enough" for simple checking, and those two other things are so immensely useful for any sort of TMP…
STL wrote:
>Implementing auto doesn’t implement decltype (C++0x’s name for what was previously called typeof) for free
Thanks for the clarification. I am aware of the differences between the two, and to me, the latter is most useful.
I am still hoping to see decltype in VC10, especially considering the fact that it has already been implemented in several compilers ( and even more for typeof).
int19h, I don’t see how you can even compare static_assert to concepts :). Implementing concepts also implies providing a fully "conceptualized" standard library, which is a huge change.
> int19h, I don’t see how you can even compare static_assert to concepts :)
I’m not. I’m just saying that static_assert does cover one particularly common request, which is to get meaningful error messages on errorneous template instantiations.
"Well, I can kind of see why, but I think missing Concepts means that you have no real C++/0x support – that’s the single most important new feature."
True, but I think it’d be silly to have expected C++0x support from VC10. I don’t know when they expect to ship VC10, but assuming they keep the trend of shipping early relative to the year it’s named after, we’ll see VC10 at some point in 2009. And C++0x is only *barely* going to make it in 2009, so at best, VC10 could implement a draft version, but certainly not the final one. It was never realistic to expect a complete C++0x implementation so soon.
"Once again us C++ developers are feeling like second class citizens. Maybe it’s time to jump ship…"
Why, exactly? Because they give us *some* new features before the standard is finalized? Unlike C#, C++ isn’t defined by the people writing the compiler. In C#, people can say "wouldn’t it be cool to add feature X", implement X in the next version of the compiler, and then add it to the C# spec.
C++ works the opposite way. A committee decides on the language features *first*, and then compiler writers try to catch up. (Of course the compiler vendors are represented in the standards committee, but the point is that the features go in the standard spec *first*, and *then* in compilers)
I’ll feel C++ is given a second-class treatment if they don’t have a decent C++0x implementation in VC11. But I can’t blame them for keeping VC10 mainly a C++03 implementation.
Anyway, good to hear that there’s more c++0x to come in VC10. I got the impression from first reading the post that this was it, these were the 0x features that would be in VC10.
> I got the impression from first reading the post that this was it, these were the 0x features that would be in VC10.
See Stephan’s post above, particularly:
"Paraphrasing our libraries and compiler front-end program manager Damien Watkins, the CTP is only the first look at our VC10 functionality and there is definitely more to come."
i just have one thing to say, disappointed about lack of typeof
In case you haven’t noticed yet, "decltype" was the only feature about which it was not said plainly, "no, it won’t be there in VC10".
So cross your fingers :)
One other question regarding lambdas: how well do they play together with C++/CLI? Particularly, can they capture:
1. Managed handles, either by value or by reference.
2. Tracking references.
Also, is there a plan to provide some easy way to make a delegate instance out of a lambda?
Well, first of all, lambdas in C++ means that LINQ is now possible. So the question is, on the C++/CLI are you implementing this?
Apart from that, I think the biggest thing which I would really like is the intellisense updates, its not as bad now processor usage wise, but it is unable to do anything useful.
> Well, first of all, lambdas in C++ means that LINQ is now possible.
No, it doesn’t. C++0x lambdas are not the same as C# 3.0 lambdas (particularly as far as lifetime is concerned). Also, for LINQ, lambdas alone are not sufficient – you actually need "expression trees". And C++0x lambdas cannot be faithfully transformed to expression trees for a number of reasons, from what I can see.
Like I said above, it is possible to write a simple wrapper function that takes a C++ lambda, and gives you a delegate of any type that might be needed. This will work for LINQ to Objects/XML/DataSet (and any other that doesn’t deal with expression trees).
"For laughs, this means that the following is valid C++0x:
int main() {
[](){}();
[]{}();
}
"
See, this is one thing I dislike about the C++ standards committee: They joke too much. For example, there’s the infamous warning in C++2003 that template specializations suck, don’t use them, but phrased as a limerick. And now they’ve decided that wouldn’t it be cute if any balanced sequence of empty braces were acceptable by the parser?
(Okay, not "any" sequence, but {{}}[]{[](){}}([](){}()); is acceptable, for example. For any given line noise, it’s getting harder and harder for a human to determine whether it’s valid C++.)
The committee should have ruled that a lambda’s body must contain at least one statement, and that an empty parameter-list must not be dropped. Also, they should not have allowed type inference in the one special case you mentioned (the case in which the lambda’s body contains only a return statement) — they should have ruled either that type inference always happened, or that it never happens.
The committee is just trying to ensure that there will never such thing as IOCCC for C++ – because it’s going to be too easy ;)
The lambdas for C++ itself may be different, but since the syntax itself has been formalised then is there anything stopping them from twiddling it a bit and getting them to work as needed under C++/CLI.
Don’t forget, C++ classes are different from the managed classes, but they kept the syntax similar but added what it needed to support the managed classes.
[int19h]
> One other question regarding lambdas: how well do they play together with C++/CLI?
I don’t know anything about managed code, but I’ve forwarded your question to JonCaves.
[Anonymous Cowherd]
> "For laughs, this means that the following is valid C++0x: …"
> See, this is one thing I dislike about the C++ standards committee: They joke too much.
That was my joke, not the Committee’s. (I’m not a Committee member.) Sometimes my silliness doesn’t involve cats, you know.
> For example, there’s the infamous warning in C++2003 that template specializations suck, don’t use them, but phrased as a limerick.
That’s incorrect. Template specializations (both explicit and partial) are extremely powerful and easily usable. The warning is:
"When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation." (C++03 14.7.3/7)
This means that you have to ensure that a specialization is declared before it’s used, which is easy unless you’re doing something excessively tricky.
> And now they’ve decided that wouldn’t it be cute if any balanced sequence of empty braces were acceptable by the parser?
That’s incorrect. This "falls out" of the grammar; it’s not some intentionally cute thing.
> The committee should have ruled that a lambda’s body must contain at least one statement
That would require *additional* Standardese, because empty compound-statements are perfectly valid. It’s also inconsistent, because named functions can have empty bodies.
> and that an empty parameter-list must not be dropped.
That would be as simple as removing the opt subscript from lambda-parameter-declaration in the definition of lambda-expression.
Someone considered making the lambda-parameter-declaration optional to be a useful feature. As I explained in my post, "Whether eliding the lambda-parameter-declaration is good style is up to you to decide."
> Also, they should not have allowed type inference in the one special case you mentioned
> (the case in which the lambda’s body contains only a return statement) — they should
> have ruled either that type inference always happened, or that it never happens.
Making the lambda-return-type-clause mandatory would produce needless verbosity (the very thing that lambdas are trying to reduce), especially given that a lot of lambdas are going to return bool. But there are real problems with always performing automatic type deduction; in particular, when there are multiple return statements returning different types. (This is easier to encounter than it sounds, especially given the usual arithmetic conversions.) Making the lambda-return-type-clause optional when and only when the lambda’s body is a single return statement is a simple and effective rule, easy to learn and remember.
If you want to make all of your lambda return types explicit, you’re certainly welcome to.
int19h: JonCaves says:
You can only pass a variable with a managed type as an argument to a lambda – you can’t capture a variable that has a managed type.
We have no plans to "merge" lambdas and delegates.
> You can only pass a variable with a managed type as an argument to a lambda – you can’t capture a variable that has a managed type.
Yep, just tried that myself. "Error C3498: ‘s’: you cannot capture a variable that has a managed type".
I can’t understand why it is the case, though. I can understand why it’s not possible to capture managed references – and C# lambdas cannot capture them for the same reason. I can also understand why it’s tricky to capture an object handle by value (though if there would be some extension syntax to force the function object created from the lambda to be a "value class", it could work). But there’s no reason why I can’t capture an object handle by reference! I mean, I can write this:
struct handwritten_lambda
{
String^& s;
handwritten_lambda(String^& s)
: s(s)
{
}
void operator() (int x)
{
s += x.ToString();
}
};
and then use it:
std::vector<int> v;
v.push_back(123);
String^ s = "Foo";
std::for_each(
v.begin(),
v.end(),
handwritten_lambda(s));
and it works, as expected! But, I cannot write this:
std::for_each(
v.begin(),
v.end(),
[&s](int x) { s += x.ToString(); });
Why? Given that C++0x lambdas essentially do the same, they should not have any restrictions on top of what the plain transformation to a function object as described in the standard has.
By the way, I have just noticed that function objects generated from lambdas do not have "result_type" typedef, and therefore std::tr1::result_of cannot be applied to them. Looking at the wording of the Standard, it seems that it does not require the lambdas to provide result_type either… is this a Committee oversight, or is it deliberate? If the latter, then what is the suggested workaround?
[int19h]
> is this a Committee oversight, or is it deliberate?
Deliberate. C++0x result_of is powered by decltype, and therefore always gets the right answer without resorting to TR1’s hackery.
> If the latter, then what is the suggested workaround?
Until you get a decltype-powered result_of, if you need to use result_of, you’ll need to use handwritten functors.
With support for the "auto" keyword, it’s a shame, you have to write
"for_each(c.begin(), c.end(), [](const typename Container::value_type& e) { cout << e << " "; });" instead of "[](auto &e ) { … }" (that would’ve been sweet, but it’s already very cool).
Purpur: The short story is that that would conflict with concepts. For the long story, see section 5.1 of the (very old) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1968.pdf .
Will constructor delegation be implemented in VC10? And also the new member initialization syntax?
class SomeClass { int Value = 5; };
It’s nice to hear lambdas will be supported in VC10. I can’t wait!!
[0xC0000005]
> Will constructor delegation be implemented in VC10?
No.
> And also the new member initialization syntax?
No.
> It’s nice to hear lambdas will be supported in VC10. I can’t wait!!
Glad to hear it. :-)
On the whole, the conclusion seems to be:
1. Major features that are going to be implemented from C++0x are mostly those that enable PPL (namely, lambdas).
2. Implementation of those new features is targeted strictly at native code, no interaction scenarios with C++/CLI are seemingly considered. (Can’t help but think that it’s because PPL is pure native, too).
Even so, lambdas alone are well worth the wait, and auto and rvalue refs are a nice bonus. And, hopefully, the rest will be coming in VC11, once the C++0x standard is finalized.
Hello,
"Not in VC10. std::reference_closure implies and requires a certain optimization (the "static scope pointer" mentioned by WP N2798) that must be supported by the compiler back-end."
Could you elaborate on that? The "pair of a function pointer and a static scope pointer" mentioned in the draft you referred to sounds like C++Builder’s __closure keyword, but I am not sure if my understanding of "static scpe pointer" is correct.
C++0x standard requires that the compiler optimizes a non-mutable lambda that only captures variables by reference to be an instance of special magic base class std::reference_closure. As described, the constraints on this class effectively enforce a limitation wherein such as instance is a pointer to the stack frame from which the variables are captured, plus a pointer to the function that is to be executed.
The reason why it is there is so that there is a standard common type that can be be used for passing and storing first-class function values (including bound ones) that is more lightweight than std::function.
VC10’s compiler obviously will just be implementing the low-hanging fruit of C++0x. The things that can quickly be implemented with a few front-end changes. This is all well and good.
However, will we have to wait for the VC11 compiler to start getting deeper into C++0x, or will Microsoft give us a VC10.1 a year or so after VC10 ships, much like how VC7.1’s compiler was much more C++98 compatible than VC7’s compiler?
Also, is Microsoft going to dedicate itself to providing a near-full C++0x compiler in VC11?
[Korval]
> will we have to wait for the VC11 compiler to start getting deeper into C++0x
Magic 8 Ball says: Cannot predict now.
> Also, is Microsoft going to dedicate itself to providing a near-full C++0x compiler in VC11?
Magic 8 Ball says: Cannot predict now. (Repetitive Magic 8 Ball is repetitive.)
Obviously, we want to implement C++0x’s features as soon as possible. (I’m drooling over variadic templates.) But we’re definitely not ready to talk about what will be in VC11.
> VC10’s compiler obviously will just be implementing the low-hanging fruit of C++0x. The things that can quickly be implemented with a few front-end changes.
I wouldn’t call lambdas "low-hanging fruit"…
Yes, we would all really like to see concepts. But, even at a quick glance, this feature will probably require a rewrite of half the code in most (all?) C++ compilers out there to produce a workable compliant implementation with decent performance. It’s just a totally different way to deal with templates than whatever was there before. I’m not really surprised that one is not coming in VC10.
Will variadic templates be implemented in VC10?
[Akira Takahashi]
> Will variadic templates be implemented in VC10?
No. (As a library dev, I *really* wanted them.)
I admit that’s impressive. I didn’t actually know that there was a way to make lambdas or type inference look complicated. Can’t wait until the C++ community starts to struggle with closures + RTTI + finally, etc.
Thanks for lambdas, auto & static_assert :)
What about constexpr – will that be implemented?
[Faisal Vali]
> What about constexpr – will that be implemented?
Not in VC10.
> I wouldn’t call lambdas "low-hanging fruit"…
Lower than most. It’s still all front-end work. It’s basically recognizing a syntax and converting it to a different syntax, with a class and operator() overload. It’s something you could do as a code-generation path with an external application, rather than as part of the compiler itself.
Compare that to, for example, variadic templates. The idea sounds simple, but the pack/unpack semantics can go almost anywhere and are very complicated to get right.
Hi. I’m Arjun Bijanki, the test lead for the compiler front-end and Intellisense engine. One afternoon
I just want to repeat the question from earlier since it seemed to get skipped. What will VC10’s support for the C99 standard look like? In particular, variable length arrays?
> What will VC10’s support for the C99 standard look like?
I didn’t see any mention of C99 in any talks on VC10 so far. So, I guess, the answer is "there won’t be one". Given that g++ doesn’t support a lot of C99 stuff either, I don’t see why would it matter – you can’t write portable C99 today anyway (too few compilers support the full spec), and this is unlikely to change anytime soon. It seems that no-one really cares about it that much.
C++0x includes the C99 Standard Library (see N2798 17.1/9).
Well, I guess library is relatively easier – once you need it (when C++0x is finalized; VC11?), you can pick it from Dinkumware as usual, and, it being a pure C library, it’s probably easier to tailor for your needs than their STL and TR1 stuff.
Language features such as struct literals and VLAs, though – I still wouldn’t expect them anytime soon. If ever. VLAs in particular, as it seems that (surprisingly) no-one else has gotten them right, either – at least the C99 status page for gcc still listed them as "broken" last time I checked.
Part 1 of this series covered lambdas , auto , and static_assert . Today, I’m going to talk about rvalue
As you may have noticed my emphasis on polyglot programming on this blog.  I’ve been following the
As you may have noticed my emphasis on polyglot programming on this blog. I’ve been following the language
As you may have noticed my emphasis on polyglot programming on this blog.  I’ve been following the
[Nacsa Sándor, 2009. január 20. – február 12.] Komplett fejlesztő környezet Windows kliens és web alkalmazások
Part 1 of this series covered lambdas , auto , and static_assert . Part 2 of this series covered rvalue
Visual Studio 2010 Beta 1 introduces a number of exciting new features for the C++ developer as we include
Many recursive algorithms have initial parameters. For example, Fibonacci Number is defined as: Fn =
Visual Studio 2010 Beta 1 is now available for download. I’ve recently blogged about how Visual C++ in
Magnificent goods from you, man. I’ve understand your
stuff previous to and you’re just extremely fantastic.
I actually like what you’ve acquired here, certainly like what you are saying and the way in which you say it.
You make it enjoyable and you still care for to keep it sensible.
I cant wait to read far more from you. This is really a great website.
There seems to be an issue with the display of this page. The post is cut out in the middle (same is happening for part 2) and I cant read it completely. Have tried it with Ubuntu and macOS and with both firefox and chrome.
The last sentence I can read is “If you forget the lambda-return-type-clause, the compiler will complain”.
bump