C++ Standards Committee Meeting in Rapperswil, June 2014(botondballo.wordpress.com)
botondballo.wordpress.com
C++ Standards Committee Meeting in Rapperswil, June 2014
http://botondballo.wordpress.com/2014/07/17/trip-report-c-standards-committee-meeting-in-rapperswil-june-2014/
10 comments
It took me some time to recognize the problem with range-for (after testing its implementation in VC 2012), and more time to work up the courage to write a Core Language proposal. I also wish next-gen range-for had gotten into C++14, but that's mostly a formality - compilers can (and often do) ship features as soon as they're voted into the Working Paper.
Note that nothing's wrong with "const auto& elem", except that it prohibits modification. On the other hand, "const auto&& elem" will typically not compile (it'll insist on binding to rvalues, which only proxy iterators return).
Note that nothing's wrong with "const auto& elem", except that it prohibits modification. On the other hand, "const auto&& elem" will typically not compile (it'll insist on binding to rvalues, which only proxy iterators return).
First off, its Great to see you on HN! For the few of you who don't know, Stephan maintains Visual Studio's C++ Standard Library implementation and he is extremely well regarded in C++ circles.
Thats of course right about const auto &&.. It won't work, I did mean (auto &&elem : range).
Thats of course right about const auto &&.. It won't work, I did mean (auto &&elem : range).
As I was reading through your "for (elem : range)" proposal I became quite anxious to know how adding const would be handled. I was hoping that "for (const elem : range)" would be added to mean "for (const auto& elem : range)" because I very often find myself within a non-const method having a non-const container but wanting to iterate with no chance of modifying it.
I was at first relieved to see this topic addressed at the top of Q&A, then disappointed to see "Just do it the old way if you want const." I feel that we don't use const enough in C++, and making it easier (yet still clear) to use would be of significant benefit.
If you agree, perhaps there is still time to support "for (const elem : range)" - it seems to me natural and no more disruptive than the rest of the proposal.
I was at first relieved to see this topic addressed at the top of Q&A, then disappointed to see "Just do it the old way if you want const." I feel that we don't use const enough in C++, and making it easier (yet still clear) to use would be of significant benefit.
If you agree, perhaps there is still time to support "for (const elem : range)" - it seems to me natural and no more disruptive than the rest of the proposal.
I talked about this some more in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n399... Q17. Many people have asked for such syntax, but I am wary of adding more complexity to the Core Language. Ultimately, I believe that this should be handled on the range side instead of the element side. What Evolution/Core needs to do is to fix the problem with nested temporaries in range-for loops - the problem (affecting both C++11's range-for and mine) is that range-for will keep temporary ranges alive if they're the topmost thing returned, but not if you have "const T& noop(const T&)" and you try to loop over noop(return_temporary_range()). They're aware of the problem, which is a start. If and when that's fixed, then what you want can be handled through library tech: "for (elem : as_const(range))".
Out of curiosity, how about making `const` the default and requiring `mutable` for mutation?
There's already a Standard precedent in form of C++11 lambdas -- and const-by-default has some technical niceties (perhaps simplicity, too -- arguably making this the default removes some complexity from the language from the beginner's point of view, e.g., by preventing accidental mutation) that may make this worth it.
// I see that you addressed the constness in A17, but I believe allowing the `mutable` opt-in, as in the lambdas, takes care of the "limiting" aspect; "confusing", OTOH, is a matter of taste -- after all, `std::for_each` operates on InputIterators as well (thus, perhaps the similarity with a non-modifying nature[1] of a Standard Library analog is arguably preferable from the consistency / least-surprise-principle point of view?), and, again, lambdas also have constness by default.
Thoughts?
// [1] -- in principle, at least (for completeness, there's an allowance for nonconstant functions w/ mutable iterators)
There's already a Standard precedent in form of C++11 lambdas -- and const-by-default has some technical niceties (perhaps simplicity, too -- arguably making this the default removes some complexity from the language from the beginner's point of view, e.g., by preventing accidental mutation) that may make this worth it.
// I see that you addressed the constness in A17, but I believe allowing the `mutable` opt-in, as in the lambdas, takes care of the "limiting" aspect; "confusing", OTOH, is a matter of taste -- after all, `std::for_each` operates on InputIterators as well (thus, perhaps the similarity with a non-modifying nature[1] of a Standard Library analog is arguably preferable from the consistency / least-surprise-principle point of view?), and, again, lambdas also have constness by default.
Thoughts?
// [1] -- in principle, at least (for completeness, there's an allowance for nonconstant functions w/ mutable iterators)
I love const, but I am strongly opposed to adding constness here - as I mentioned, the non-Standard "for each" extension did that, and it caused endless confusion. Note that the lambda precedent is not actually applicable, because it affects only value captures. Reference captures can always be written through. The purpose of next-gen range-for is to operate in-place, i.e. with reference semantics.
for_each() does not add constness, and can modify elements in-place. The fact that it is grouped with the "non-modifying algorithms" is a confusing historical artifact (and was actually the subject of the first Library Issue I had a part in filing) - the algorithm itself does not modify things (unlike sort(), say) but the given functor can.
for_each() does not add constness, and can modify elements in-place. The fact that it is grouped with the "non-modifying algorithms" is a confusing historical artifact (and was actually the subject of the first Library Issue I had a part in filing) - the algorithm itself does not modify things (unlike sort(), say) but the given functor can.
Thanks for the reply!
Interesting that the constness in `for each` caused confusion (did it offer a `mutable` opt-in, though?), would intuitively expect it to be the POLS behavior. I guess given that you were probably receiving feedback on that, I will take it as something to be acknowledged.
I can see the reference semantics point, in this context the difference from the lambdas seems to make more sense.
// Just to explore another avenue, again mostly out of curiosity :-), how realistic (from the impl. POV) would be to have value-semantic range-based `for` with _mandated_ copy elision whenever possible?
True about `std::for_each`, that's what I've referred to as the "allowance" for the mutable iterators, wasn't aware about the grouping being merely a historical artifact, though. I've always felt a bit dirty using it for mutation[1], it seems that maybe unnecessarily so :-)
// [1] -- perhaps due to the algorithm being specified in terms of the InputIterator concept; hm, that being said, I suppose that while it only guarantees that we can read (dereferenced) `it`, it doesn't say that `it` _itself_ has to be immutable (right?), so it could be that I should think of a better metaphor to internalize. How do you think about InputIterators?
Interesting that the constness in `for each` caused confusion (did it offer a `mutable` opt-in, though?), would intuitively expect it to be the POLS behavior. I guess given that you were probably receiving feedback on that, I will take it as something to be acknowledged.
I can see the reference semantics point, in this context the difference from the lambdas seems to make more sense.
// Just to explore another avenue, again mostly out of curiosity :-), how realistic (from the impl. POV) would be to have value-semantic range-based `for` with _mandated_ copy elision whenever possible?
True about `std::for_each`, that's what I've referred to as the "allowance" for the mutable iterators, wasn't aware about the grouping being merely a historical artifact, though. I've always felt a bit dirty using it for mutation[1], it seems that maybe unnecessarily so :-)
// [1] -- perhaps due to the algorithm being specified in terms of the InputIterator concept; hm, that being said, I suppose that while it only guarantees that we can read (dereferenced) `it`, it doesn't say that `it` _itself_ has to be immutable (right?), so it could be that I should think of a better metaphor to internalize. How do you think about InputIterators?
> did it offer a `mutable` opt-in, though?
Nope.
> would intuitively expect it to be the POLS behavior.
If you give me (the implementation) a modifiable range, and I invisibly add constness before giving you back an element, that's surprising. C++ doesn't add constness by default anywhere (with the novel exception of lambda function call operators). If you give me a modifiable range, the least surprising thing to do is to give you a modifiable element, because that's what all of ptr[idx], * ptr, and * iter would do.
> how realistic (from the impl. POV) would be to have value-semantic range-based `for` with _mandated_ copy elision whenever possible?
If you say "for (auto elem : range) { elem = stuff; }" the write to the elem-copy will be dropped on the floor. Copy elision can't solve that.
> it doesn't say that `it` _itself_ has to be immutable (right?)
Correct.
> How do you think about InputIterators?
The concept is single-pass, read-only, but a given iterator may be stronger. for_each() is kind of special (it's the only algorithm that takes InputIterators, yet allows stronger iterators to be used with modifying functors), but other algorithms are vaguely similar. For example, transform(InIt first, InIt last, OutIt result, UnOp op) permits transform(first, last, first, op) for an in-place transformation - here, first/last's type clearly has to be InIt and OutIt simultaneously, i.e. a mutable FwdIt iterator or stronger.
Nope.
> would intuitively expect it to be the POLS behavior.
If you give me (the implementation) a modifiable range, and I invisibly add constness before giving you back an element, that's surprising. C++ doesn't add constness by default anywhere (with the novel exception of lambda function call operators). If you give me a modifiable range, the least surprising thing to do is to give you a modifiable element, because that's what all of ptr[idx], * ptr, and * iter would do.
> how realistic (from the impl. POV) would be to have value-semantic range-based `for` with _mandated_ copy elision whenever possible?
If you say "for (auto elem : range) { elem = stuff; }" the write to the elem-copy will be dropped on the floor. Copy elision can't solve that.
> it doesn't say that `it` _itself_ has to be immutable (right?)
Correct.
> How do you think about InputIterators?
The concept is single-pass, read-only, but a given iterator may be stronger. for_each() is kind of special (it's the only algorithm that takes InputIterators, yet allows stronger iterators to be used with modifying functors), but other algorithms are vaguely similar. For example, transform(InIt first, InIt last, OutIt result, UnOp op) permits transform(first, last, first, op) for an in-place transformation - here, first/last's type clearly has to be InIt and OutIt simultaneously, i.e. a mutable FwdIt iterator or stronger.
Thanks for the explanations!
I've had the same experience. Hadn't really touched C++ since the late 90's and had traumatic memories from those times but working in my own C++11 codebase recently has been both pleasant and surprisingly productive. The language is headed in the right direction but it's a big ship to steer.
I love the language, but mostly on personal projects.
For the typical enterprise developer, at least in many of our projects, I am happy that we manly use other languages.
I feel like crying every time I see C style coding in C++, with its usual set of security exploits.
For the typical enterprise developer, at least in many of our projects, I am happy that we manly use other languages.
I feel like crying every time I see C style coding in C++, with its usual set of security exploits.
I'm pretty glad we use C++ in enterprise development (and extra glad we use C++11) ;) There are barely any other languages which can replace it yet. Rust is a good candidate.
You're lucky to be able to use such a recent standard in enterprise dev. Those shops tend to be pretty conservative in my experience. Where do you work?
It happened fairly recently, after the switch to the newest gcc, because we basically decoupled the compiler from the underlying distro (using cross compilation), so compiler could be updated independently. For a long time we were stuck with an old gcc.
[deleted]
Well I imagine you are lucky to work in an enterprise world where you get to pick skilled developers and are allowed to make proper use of C++.
I have seen quite a few projects with developers that could barely handle VB, being thrown to C++ projects.
Others where the style guide was making it, C compiled with a C++ compiler.
I have seen quite a few projects with developers that could barely handle VB, being thrown to C++ projects.
Others where the style guide was making it, C compiled with a C++ compiler.
> I have seen quite a few projects with developers that could barely handle VB, being thrown to C++ projects.
I'm not sure why would anyone do that, if they want to produce a quality result. Finding good programmers and engineers is hard though.
> Others where the style guide was making it, C compiled with a C++ compiler.
Yes, that can be pretty annoying, and I had to deal with maintaining such code in the past. Luckily this doesn't happen anymore in our development.
I'm not sure why would anyone do that, if they want to produce a quality result. Finding good programmers and engineers is hard though.
> Others where the style guide was making it, C compiled with a C++ compiler.
Yes, that can be pretty annoying, and I had to deal with maintaining such code in the past. Luckily this doesn't happen anymore in our development.
> I'm not sure why would anyone do that, if they want to produce a quality result.
Pay as less as possible for project costs.
Pay as less as possible for project costs.
[deleted]
Making Cairo C API a C++ standard, through automatic conversion, looks all kinds of wrong to me. The result is not properly generified like Boost GIL, and it carries vaguely defined implementation details like for example font hinting style from freetype (not even cairo library itself). I hope this and the ABI proposal will never make it as the C++ TS or standard.
[deleted]
"Modules is, in my opinion, one of the most sorely needed features in C++. They have the potential of increasing compile times by an order of magnitude or more, thus bringing compile-time performance more in line with more modern languages, ..."
Presumably that should be "decreasing", not "increasing" (or "compilation speed" rather than "compile times").
Presumably that should be "decreasing", not "increasing" (or "compilation speed" rather than "compile times").
Shameless plug for my implementation of the Executors & Schedulers TS: https://github.com/en4bz/executors
[deleted]
(cheering)
modules ! modules ! modules !
modules ! modules ! modules !
The extern "abi" for an Application Binary Interface would be so useful.
The information seems pretty exciting, but I still don't feel like I have fully grasped the changes in C++11 yet. What are some good resources for getting up to speed with the latest and greatest C++?
Scott Meyers has an Introduction: http://www.artima.com/shop/overview_of_the_new_cpp
He's also writing a new book that's available in Rough Cuts from O'Reilly that covers C++11/14: http://scottmeyers.blogspot.com/2014/06/effective-modern-c-s... and has given a talk covering some of the same ground: http://vimeo.com/97318797
Herb Sutter has "Elements of Modern C++ Style": http://herbsutter.com/elements-of-modern-c-style/ and has given several talks, such as http://channel9.msdn.com/Events/Build/2014/2-661
Finally, you can't really beat Stroustrup's book: http://www.amazon.com/The-Programming-Language-4th-Edition/d...
He's also writing a new book that's available in Rough Cuts from O'Reilly that covers C++11/14: http://scottmeyers.blogspot.com/2014/06/effective-modern-c-s... and has given a talk covering some of the same ground: http://vimeo.com/97318797
Herb Sutter has "Elements of Modern C++ Style": http://herbsutter.com/elements-of-modern-c-style/ and has given several talks, such as http://channel9.msdn.com/Events/Build/2014/2-661
Finally, you can't really beat Stroustrup's book: http://www.amazon.com/The-Programming-Language-4th-Edition/d...
If you already know C++ and just want to get up to speed with C++11/14 features, I wrote several books aimed at specific feature sets supported by different compilers (GCC, Clang, MSVC). Check them out at http://cpprocks.com.
Glad to see named parameters and introspection on the table
What is the motivation behind including Cairo?
Herb wants new users to be able to draw graphics without using third party toolkits. It is not meant to be all encompassing, but if you need custom 2d it is a nice feature, albeit very out of scope of a standard library implementation.
It is pretty much in scope. We old timers remember the days when compilers came with graphics libraries.
So why forcing everyone to jump through hurdles just to do some simple uses of 2D programming?
So why forcing everyone to jump through hurdles just to do some simple uses of 2D programming?
Because, I guess, Swing. Unless the standard compels implementations to use platform native windowing systems and theming engines (since you can't really leave it out if you want visual output) then its going to be an ugly mess. And, for example, a huge amount of Qt is just native theming on all its supported platforms.
The point is not replace WxWidgets, Qt or flavor of the month GUI framework.
Plain simple 2D graphics like BGI, to allow any C++ beginner not to worry which bazillion libraries s/he needs to download to draw some colored squares.
Plain simple 2D graphics like BGI, to allow any C++ beginner not to worry which bazillion libraries s/he needs to download to draw some colored squares.
[deleted]
The (elem : range) proposal seen here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n385...
I'm really looking forward to as well. I wish it could have been in C++14. STL (the guy) is right when he says (auto elem : range) is very tempting. Its so easy for a novice user to not understand they are making a ton of potentially (and likely) unneeded copies. Also in code review its quite common, to see (const auto &elem : range) when it should be (const auto &&elem : range).
After getting bogged down years ago in a crappy C++03 codebase I eased off C++ for a few years, but i must say, the language is really getting better. 5 years ago if you would have told me I would be looking forward to writing something major in C++ I would have laughed.