Why is the restrict keyword not part of C++? - c++

The title says it all. I am curious why is the restrict keyword not part of C++ ? I don't know much about C++, and I'm still not able to find anything online that would give a reason blocking this. Does anyone know what terrible things would happen, if a C++ standard would use this keyword similarly to the way C does? Is it just not needed at all?
More explanation: It is not about using it, perhaps I will not have any benefit from this keyword in my whole life. This question is only about curiosity, since restrict is part of C since C99, that is 15 years.
Read this as well:
I'm interested in technical reasons, not opinions like "They just didn't like, it is not cool enough"

There are several issues in defining "restrict" in C++, some of them are listed in WG paper N3635: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3635.pdf "Towards restrict-like semantics for C++"
Some possible issues with restrict in C++ are:
Restrict Class members and indirection with “this pointer”
Passing of restrict qualifiers into functions, functors, lambdas, and templates
Escaping of restrict pointer values inside functions
Overlapping array members, strides
Document also list several C++ compilers with limited "restrict" support for C++.
There is also interesting history note in N3635 about non-inclusion of restrict to C++:
At the time of reviewing C99 feature inclusion in C++ during the Mont Tremblant meeting, restrict was considered but was waiting a paper proposal although none came forward....
Restrict is a C99 feature and was never designed to work in class abstractions and it may have to do with that pointers are not common in C++. ... it was designed for fine-grain aliasing for C, but not well-designed for type-based aliasing in C++

Not to detract from osgx's answer, but - there is a somewhat more up-to-date paper, N3998 by Finkel, Tong, Carrouth, Nelson Vandevoode and Wong, from May 2014:
Towards restrict-like aliasing semantics for C++
And an ever newer one from 2018:
[[assert: std::disjoint(A,nA, B,nB)]]: Contract assertions as an alternate
spelling of ‘restrict’
(Thanks #MCCCS for pointing the last one out.)

Related

Situation with `restrict` keyword/attribute in C++ standard

In short, restrict is supposed to tell the compiler that the pointers cannot point into the same memory location. Which is very useful for, say, function arguments and further compiler optimization. In scientific computing, restrict is very widely used.
Currently, restrict keyword is only a part of C99, but not a part of C++. We know that a lot of C++ compilers support __restrict__ as an extension. This question also talks in detail about what restrict and __restrict__ do.
Now, the discussion in the aforementioned question happened a long time ago and does not talk about C++17, C++20, nor plans for future standards. I found n3988 proposal that discusses restrict-like aliases in C++, complexities with richer syntaxis in C++, and potential remedies.
According to the IBM blog (2014), n3988 was encouraged for future work.
This question talks about the history of restrict and C++ without anything conclusive regarding the actual implementation and mentions the papers I already listed or the one mentioned in the comments (p1296).
I was not able to find anything beyond that on the plans of supporting restrict in the upcoming C++ (as far as I know, it's not a part of C++17). It seems like a very useful functionality, so I wonder
if I missed something in terms of proposals/discussion?
is there other information on the restrict usage in C++?
are there alternative ways to make the compiler optimizations (allowed by __restrict__) possible by using only "standard" functionality?
Nothing like C’s restrict is in even C++20. The paper already mentioned was well-received at a preliminary presentation in November 2018, perhaps because it avoids the critical difficulty with a qualifier—that no one, even in C, understands how it interacts with the rest of the type system. Part of this is because adding restrict doesn’t change the meaning of any one pointer, but affects its relationship with some set of other pointers (whose membership is not well-specified) based on what arithmetic is performed with them later. Another part is because C++ allows so many operations with types: what would std::vector<T *restrict> mean, and what would be the type of indexing a std::vector<T> &restrict?
Just what practical optimization opportunity will be offered by such a contract-based approach is not yet clear; there are still many unanswered questions about contracts and optimization in general.

Why allow function declarations inside function bodies

Why does the syntax allow function declarations inside function bodies?
It does create a lot of questions here on SO where function declarations are mistaken for variable initializations and the like.
a object();
Not to mention most vexing parse.
Is there any use-case that is not easily achieved by the more common scope hiding means like namespaces and members?
Is it for historical reasons?
Addendum: If for historical reasons, inherited from C to limit scope, what is the problem banning them?
Whilst many C++ applications are written solely in C++ code, there are also a lot of code that is some mixture of C and C++ code. This mixture is definitely something of C++'s important part of its usefulness (including the "easy" interfacing to existing API's, anything from OpenGL or cURL to custom hardware drivers that are written in C, can pretty much be used directly with very little effort, where trying to interface your custom hardware C driver into a Basic interpreter is pretty diffcult)
If we start breaking that compatibility by removing things "for no particular value", then C++ is no longer as useful. Aside from giving better error messages in a condition that is confusing, which of course is useful in itself, it's hard to see how it's useful to REMOVE this - and that's of course assuming NONE of the C++ is using this in itself - and I wouldn't be surprised if it DOES happen at times even in modern code (for whatever good or bad reasons).
In general, C++ tries very hard to not break backwards compatibility - and this, in my mind, is a good thing. That's why the keyword static is used for a bunch of different things, rather than adding a new keyword, and auto means something different now than it used to in C, but it's not a "new" keyword that could break existing code that happened to use whatever other word chosen (and that is a small break, but nobody really used it for the past 20 years anyway).
Well, the ability to declare functions within function bodies is inherited from C so, by definition, there is a reason involving historical and backward-compatibility reasons. When there is likely to be real-world code which uses a feature, the argument to remove that feature from the language is weakened.
People - particularly those who only use the latest version of the language, and are not required to maintain legacy code - do tend to under-estimate how strong an argument backward compatibility is in C++. The original C++ standard was specifically required to maintain backward compatibility with C. As a rough rule, standards discourage removing old features if doing so is likely to break existing code. It can be done, however, if the only possible usage causes a danger that cannot be prevented (which is reason for removal of gets(), for example).
When maintaining legacy code there are often significant costs with updating a code base to replace all instances of an old construct with some modern replacement. A coding change that may be insignificant for a hobbyist programmer may be extremely costly when maintaining large-scale code bases in regulatory environments, where it is necessary to provide formal evidence and audit trail that the change of code does not affect ability to meet its original requirement.
There are certain programming styles where it is useful to be able to limit the scope of any declarations. Not everyone uses such programming styles, but the reason such features are in the language is to allow the programmer the choice of programming technique. And, whether advocates of removing such features like it or not, there is a certain amount of code which uses such constructs usefully. That significantly weakens the case for removing the feature from the language.
These sorts of arguments will tend to come up for languages that are used in large-scale development, to develop systems in regulatory environments, etc etc. C and C++ (and a number of other languages) are used in such settings, so will tend to accumulate some set of features for "historical" or "backward compatibility" reasons. It is possible to make a case for removing such features by providing evidence that the feature is not in real-world use. But, since the argument is about justifying a negative claim, that is difficult (all it needs is someone to provide ONE example of continuing real-world beneficial usage and suddenly a counter-example exists which supports the case for keeping the feature).

Why were concepts (generic programming) conceived when we already had classes and interfaces?

Also on programmers.stackexchange.com:
I understand that STL concepts had to exist, and that it would be silly to call them "classes" or "interfaces" when in fact they're only documented (human) concepts and couldn't be translated into C++ code at the time, but when given the opportunity to extend the language to accomodate concepts, why didn't they simply modify the capabilities of classes and/or introduced interfaces?
Isn't a concept very similar to an interface (100% abstract class with no data)? By looking at it, it seems to me interfaces only lack support for axioms, but maybe axioms could be introduced into C++'s interfaces (considering an hypothetical adoption of interfaces in C++ to take over concepts), couldn't them? I think even auto concepts could easily be added to such a C++ interface (auto interface LessThanComparable, anyone?).
Isn't a concept_map very similar to the Adapter pattern? If all the methods are inline, the adapter essentially doesn't exist beyond compile time; the compiler simply replaces calls to the interface with the inlined versions, calling the target object directly during runtime.
I've heard of something called Static Object-Oriented Programming, which essentially means effectively reusing the concepts of object-orientation in generic programming, thus permitting usage of most of OOP's power without incurring execution overhead. Why wasn't this idea further considered?
I hope this is clear enough. I can rewrite this if you think I was not; just let me know.
There is a big difference between OOP and Generic Programming, Predestination.
In OOP, when you design the class, you had the interfaces you think will be useful. And it's done.
In Generic Programming, on the other hand, as long as the class conforms to a given set of requirements (mainly methods, but also inner constants or types), then it fits the bill and may be used. The Concept proposal is about formalizing this, so that detection may occur directly when checking the method signature, rather than when instantiating the method body. It also makes checking template methods more easily, since some methods can be rejected without any instantiation if the concepts do not match.
The advantage of Concepts is that you do not suffer from Predestination, you can pick a class from Library1, pick a method from Library2, and if it fits, you're gold (if it does not, you may be able to use a concept map). In OO, you are required to write a full-fledged Adapter, every time.
You are right that both seem similar. The difference is mainly about the time of binding (and the fact that Concept still have static dispatch instead of dynamic dispatch like with interfaces). Concepts are more open, thus easier to use.
Classes are a form of named conformance. You indicate that class Foo conforms with interface I by inheriting from I.
Concepts are a form of structural and/or runtime conformance. A class Foo does not need to state up front which concepts it conforms to.
The result is that named conformance reduces the ability to reuse classes in places that were not expected up front, even though they would be usable.
The concepts are in fact not part of C++, they are just concepts! In C++ there is no way to "define a concept". All you have is, templates and classes (STL being all template classes, as the name says: S tandard T emplate L ibrary).
If you mean C++0x and not C++ (in which case I suggest you change the tag), please read here:
http://en.wikipedia.org/wiki/Concepts_(C++)
Some parts I am going to copy-paste for you:
In the pending C++0x revision of the C++ programming language, concepts and the related notion of axioms were a proposed extension to C++'s template system, designed to improve compiler diagnostics and to allow programmers to codify in the program some formal properties of templates that they write. Incorporating these limited formal specifications into the program (in addition to improving code clarity) can guide some compiler optimizations, and can potentially help improve program reliability through the use of formal verification tools to check that the implementation and specification actually match.
In July 2009, the C++0x committee decided to remove concepts from the draft standard, as they are considered "not ready" for C++0x.
The primary motivation of the introduction of concepts is to improve the quality of compiler error messages.
So as you can see, concepts are not there to replace interfaces etc, they are just there to help the compiler optimize better and produce better errors.
While I agree with all the posted answers, they seem to have missed one point which is performance. Unlike interfaces, concepts are checked in compile-time and therefore don't require virtual function calls.

C++0X Concepts are gone. Which other features should go too? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
As you may have heard, the last meeting of the C++ standards committee voted to remove concepts from the next C++ standard. Of course, this will affect other features and would seem to throw the standard wide open again. If that is the case, which other features do you think should be stripped away (or added), and why?
Links:
Removal of Concepts -- Danny Kalev (on the decision to remove concepts)
Simplifying the use of Concepts -- Bjarne Stroustrup (on the problems with concepts as they look now)
The Long Pole Gets Longer -- Martin Tasker (on the impact to the schedule for C++0x if concepts have to be fixed)
The C++0x "Remove Concepts" Decision - Stroustrup on the issue on Dr. Dobbs
Trip Report: Exit Concepts, Final ISO C++ Draft in ~18 Months - Herb Sutter
Concepts Get Voted Off The C++0x Island - Jeremy Siek defending the current Concepts spec
What Happened in Frankfurt? - Doug Gregor on C++Next (on the history and removal of Concepts).
Of course, this will affect other
features and would seem to throw the
standard wide open again.
Hardly. They still want to wrap up the standard soon, which is one of the main reasons for removing concepts. Making it "wide open" to unrelated changes would just throw away everything they gained by ditching concepts.
Anyway.... Of the remaining C++0x additions, I can't think of anything else I'd want to remove. I agree with their decision regarding concepts though. Stroustrup's paper really outlined some serious problems, The current specification for concepts would admittedly simplify template error messages, but it would do so by dramatically reducing the usefulness of generic programming -- a price I'm not willing to pay.
When I first read that paper, it scared me, because I assumed it was too late in the process for making serious changes to the spec. Turns out it wasn't, and the committee was willing to take dramatic action.
But apart from this, I think C++0x is in good shape. The remaining new features all look worthwhile.
Of course, there are plenty of existing features I'd love to remove. Primarily the vector<bool> specialization. There are other popular examples of features that didn't work out (the export keyword, exception specifications), but the vector specialization is the only one of them that can't be ignored. As long as we don't try to export templates, it doesn't matter that the keyword exists (and isn't implemented by compilers), and we can just refrain from using exception specs, but every time we need a vector of bools, we're bitten by the stupid premature optimization that slipped into the current standard.
Unfortunately, it seems like they've given up on removing it. (Last I checked, it wasn't even deprecated).
Of course, plenty of old C cruft could be ditched too, but recently, I've discovered that the one change I'd really love to see is...... ditching the Iostreams library. Toss it out, and build a new STL-style I/O library based on generic programming.
The current OOP-styled Iostreams library is ugly, slow, overcomplicated and inflexible. There's too much voodoo involved in defining new streams, too few standard stream types involved, too little flexibility (the problem that made me realize how limited the library is, was that I needed to extract a float from a string. Easy to do with stringstream, but if you need to do it often, you don't want to have to copy the input string every time (as the stringstream does) -- where's the stream that works on an existing iterator range? Or a raw array, even?)
Throw IOstreams out, develop a modern replacement, and C++ will be vastly improved.
And perhaps do something about the string class as well. It works sort of ok'ish as it is now, but really, what's with the huge number of member functions? Most of them would work better, and be more general, as free functions. Too much of the standard library relies specifically on the string class, when it could in principle work with any container, or even an iterator (std::getline, I'm looking at you)
Personally, I want C++ to finally break away from C. No more pre-processor, no more header files. I basically want D, but without all the stuff that D tacks on, using the STL.
None, I think the rest of the draft was great - a large number of very small pieces that can be correctly implemented independently, allowing vendors to evolve toward complete support and allowing users to take a "shopping list" approach.
Quite a different situation with contracts, as they were like a whole new parallel type system and would have been very likely to have led to different compilers ending up with their own backward compatibility problems, very similar to CSS in web browsers.
There are two things I think should be added to C++0x, I've thought of both these myself and then found that others have suggested them before but it doesn't seem like they're going to happen.
1. Defaulting Move Constructors and Move Assignment Operators
Writing a move constructor is a manual and error prone activity, if a member is added it must be added to the move constructor and assignment operators and std::move must be used religiously. That's why I think these functions should be defaultable.
movable(movable&&) = default;
movable& operator=(movable&&) = default;
Edit (2009-10-01): Looks like this is going to happen after all.
2. Override Type Deduction for Expression Templates
Expression templates often define types that should not be used directly, a case in point is the return value of std::vector<bool> operator[](size_type n), if auto or decltype are used on this kind of object unexpected behaviour may ensue.
Therefore a type should be able to say what type it should be deduced to be (or prevent deduction using = delete syntax).
Example for vector addition.
// lazy evaluation of vector addition
template<typename T, class V1, class V2>
class vector_add {
V1& lhs_;
V2& rhs_;
public:
T operator[](size_t n) const
{ return lhs_[n] + rhs_[n]; }
// If used by auto or decltype perform eager creation of vector
std::vector<T> operator auto() const
{
if (lhs_.size() != rhs_.size())
throw std::exception("Vectors aren't same size");
std::vector<T> vec;
vec.reserve(lhs_.size());
for (int i = 0; i < lhs_.size(); ++i)
vec.push_back(lhs_[i] + rhs_[i]);
return vec;
}
To me the problem is not what other features should be stripped away, but how complex will other features be after concepts have been removed. That and how much longer will it take for the rest of the features to be rephrased without concepts.
A lot of features assumed that concepts would be accepted into the language and the wording is expressed in terms of concepts. (I wonder if any proposed feature depends on concepts).
I also wonder how other libraries will evolve (think boost::type_traits) to take the niche left by concepts. Part of what concepts provided can be implemented (even if in a more cumbersome way) in terms of traits applied to the type arguments.
To me, the most important thing that concepts added to the language was an expressive formulation of compilation errors, which is nowadays one of the places where C++ is most criticized.
R.I.P. concepts.
Do whatever you want with concepts, but for god's sake keep threads and atomics, we absolutely need them. Perhaps add thread groups and support for cooperative threads a.k.a. fibers. IMO these are far more important than concepts, because everyone uses/will soon be using threads.
I'd like to remove =delete.
There's already a common and accepted idiom for acheiving the same effect (declare the function in question as private). I think this feature will just generate lots of 'I used =delete to remove a base class function from my derived class, but it can still be called using a base class pointer' questions.
Not to mention confusing people between the (now) two meanings of the delete keyword.
Strip away the pages of error messages on template code!
IIRC concepts should solve a big C++ coder problem: Human readable error messages for the STL. Its bad news that this issue isn't addressed.
The un-named function / lambda function stuff makes me nervous. Function objects are perfectly good and are explicit, thus easier to read and find.
On the other hand I kinda liked concepts, though I certainly would not have used them every day.

C++11: a new language?

Recently I started reading (just a bit) the current draft for the future C++11 standard.
There are lots of new features, some of them already available via Boost Libs. Of course, I'm pretty happy with this new standard and I'd like to play with all the new features as soon as possibile.
Anyway, speaking about this draft with some friends, long-time C++ devs, some worries emerged. So, I ask you (to answer them):
1) The language itself
This update is huge, maybe too huge for a single standard update. Huge for the compiler vendors (even if most of them already started implementing some features) but also for the end-users.
In particular, a friend of mine told me "this is a sort of new language".
Can we consider it a brand new language after this update?
Do you plan to switch to the new standard or keep up with the "old" standard(s)?
2) Knowledge of the language
How the learning curve will be impacted by the new standard?
Teaching the language will be more difficult?
Some features, while pretty awesome, seem a bit too "academic" to me (as definition I mean). Am I wrong?
Mastering all these new additions could be a nightmare, couldn't it?
In short, no, we can't consider this a new language. It's the same language, new features. But instead of being bolted on by using the Boost libs, they're now going to be standard inclusions if you're using a compiler that supports the 0x standard.
One doesn't have to use the new standard while using a compiler that supports the new standard. One will have to learn and use the new standard if certain constraints exist on the software being developed, however, but that's a constraint with any software endeavor. I think that the new features that the 0x standard brings will make doing certain things easier and less error prone, so it's to one's advantage to learn what the new features are, and how they will improve their design strategy for future work. One will also have to learn it so that when working on software developed with it, they will understand what's going on and not make large boo-boos.
As to whether I will "switch to the new standard", if that means that I will learn the new standard and use it where applicable and where it increases my productivity, then yes, I certainly plan to switch. However, if this means that I will limit myself to only working with the new features of the 0x standard, then no, since much of my work involves code written before the standard and it would be a colossal undertaking to redesign everything to use the new features. Not only that, but it may introduce new bugs and performance issues that I'm not aware of without experience.
Learning C++ has always been one of the more challenging journeys a programmer can undertake. Adding new features to the language will not change the difficulty of learning its syntax and how to use it effectively, but the approach will change. People will still learn about pointers and how they work, but they'll also learn about smart pointers and how they're managed. In some cases, people will learn things differently than before. For example, people will still need to learn how to initialize things, but now they'll learn about Uniform Initialization and Initializer Lists as primary ways to do things. In some cases, perhaps understanding things will be easier with the addition of the new for syntax for ranges or the auto return type in a function declaration. I think that overall, C++ will become easier to learn and use while at the same time becoming easier to teach.
Mastering a language is a long-term goal, it can not be done over night. It's silly to think that one can have mastery over something as complex as C++ quickly. It takes practice, experience and debugging code to really hammer something in. Academically learning is one thing, but putting to use that knowledge is an entire different monster. I think that if one already has mastery of the C++ language, the new concepts will not pose too much of a burden, but a new comer may have an advantage in that they won't bother learning some of the more obsolete ways of doing things.
1) The language itself
As far as I'm aware, there are really no breaking changes between
C++'03 and C++'0x. The only one I can think of here relates to using
auto as a storage class specifier, but since it had no semantic
meaning I don't see that being an issue.
There are a lot of other academic fixes to the standard which are very
necssary, for example better descriptions for the layout of member
data. Finally, with multi-core/cpu architectures becoming the norm,
fixing the memory model was a must.
2) Knowledge of the language
Personally, I feel that for 99.9% of C++ developers the newer language is going to be easier to use. I'm specifically thinking of features such as auto, lambda's and constexpr. These features really should make using the language more enjoyable.
At a more advanced level, you have other features such as variadic
templates etc that help the more advanced users.
But there's nothing new here, I'm still surprised at the amount of
everyday C++ developers that haven't used (or even heard of) the STL.
From a personal perspective, the only feature I'm a bit concerned about in the new standard is that of concepts. As it is such a large change, the same problems that occurred with templates (ie. completely broken implementations) is a real danger.
Update post FDIS going out for voting:
As it happens, 'concepts' was dropped for C++ 0x and will be taken up again for C++ 1x. In the end there are some changes other than auto which could break your code, but in practise they'll probably be pretty rare. The key differences can be found in Appendix C.2 of the FDIS (pdf).
For me, one of the most important, will be:
unique_ptr + std::move() !
Imagine:
Smart pointer without any overhead:
no reference counting operations
no additional storage for reference counter variable
Smart pointer that can be moved, ie. no destructor/constructor calls when moved
What does this give you? Exception safe, cheap (pointers..) containers without any costs. The container will be able to just memcpy() unique_ptrs, so there will be no performance loss caused by wrapping regular pointer by smart pointer! So, once again:
You can use pointers
It will be safe (no memory leaks)
It will cost you nothing
You will be able to store them in containers, and they will be able to do "massive" moves (memcpy-like) with them cheaply.
It will be exception safe
:)
Another point of view:
Actually, when you move group of objects using copy(), there is constructor and destructor call for every object instance. When you copy 1000 objects of 1kb size, there will be at least one memcpy() and 2000 function calls.
If you would want to avoid the thousands of calls, you would have to use pointers.
But pointers are: dangerous, etc. Actual smart pointers will not help you, they solve other problems.
There is no solution for now. You must pay for C++ RAII/pointer/valuevars design from time to time. But with C++0x, using unique_ptr will allow to do "massive" moves of objects (yes, practically objects, because pointer will be smart) without "massive" constructor/destructor calls, and without risk of using pointers! For me, this is really important.
It's like relaxing the RAII concept (because of using pointers) without loosing RAII benefits. Another aspect: pointer wrapped in unique_ptr() will behave in many aspects similar to java reference object variable. The difference is that unique_ptr() will be able to exist in only one scope at a time.
Your friend is partially right but mostly wrong: it's the same language with extra features.
The good thing is, you don't have to master all the new features. One of the primary mandates for a standards body is to not break existing code, so you'll be able to go on, happily coding in your old style (I'm still mostly a C coder even though I do "C++" applications :-).
Only when you want to have a look at the new features will you need to bone up on the changes. This is a process you can stretch over years if need be.
My advice is to learn what all the new features are at a high level (if only to sound knowledgeable in job interviews) but learn the details slowly.
In some respects, C++0x should be easier to teach/learn than current C++:
Looping through a container - the new for syntax is far easier than for_each + functor or looping manually using iterators
Initialising containers: we'll be able to initialise sequences with the same syntax as arrays
Memory management: out goes dodgy old auto_ptr, in comes well-defined unique_ptr and shared_ptr
Lambdas, although necessarily more complex than other languages' equivalents, will be easier to learn than the C++98 process of defining function objects in a different scope.
Do you plan to switch to the new standard or keep up with the "old" standard(s)?
A year ago, I was writing strict C89, because the product in question was aggressively portable to embedded platforms, some of which had compilers with radically different ideas of which bits of C99 it's worth supporting. So a 20-year-old standard still hasn't been fully replaced by its 10-year-old successor.
So I don't expect to be able to get away from C++03 any time soon.
I do expect to use C++0x features where appropriate. Just as I use C99 features in C code, and gcc extensions in C and C++ (and would use MSVC extensions, although I've never worked on MSVC-only code for more than trivial amounts of time). But I expect it to be "nice to have" rather than baseline, pretty much indefinitely.
You have a point, but it's always been the case. There is a lot of C++ code out there that still doesn't incorporate anything from the '98 standard just because of the innate conservatism of some coders. Some of us remember a dark time before the std:: namespace (before namespaces, in fact), when everyone wrote their own string class, and pointers walked around naked all the time. There is a reason why we talk about "modern C++ style" - to distinguish from the earlier style because some people still have to maintain or update code in that style.
Any language has to evolve to survive, and any language that evolves will have a divided user base, if only because people vary in their attitude towards estimating opportunity costs in applying new language features to their own work.
With the advent of C++0x in shipping compilers, this conversation will be played out over and over in dev teams across the world:
YOUNGSTER: I've just discovered these things called lambdas! And I'm finding lots of ways to use them to make our code more expressive! Look, I rewrote your old Foo class, isn't that much neater?
OLDSTER: There was nothing wrong with my old Foo class. You're just looking for excuses to use a "cool" new feature unnecessarily. Why do you keep trying to make my life so complicated? Why do I keep having to learn new things? We need another war, that's what we need.
YOUNGSTER: You're just too stuck in your ways, old man, we shouldn't even be using C++ these days... if it was up to me -
OLDSTER: If it was up to me we'd have stuck with PL/1, but no... my wife had to vote for Carter and now we're stuck with all this object-oriented crap. There's nothing you can do with std::transform and lambdas that I can't do with a goto and a couple of labels.
etc.
Your programming career will always involve learning and re-learning. You can't expect c++ to stay the same till you retire and to be using the same methods and practises that you were using 40 years ago. Technology rolls on, and it rolls quickly. It's your job to keep up with it. Of course you can ignore that, and continue to work the same way you currently do, but in 5 / 10 years time you'll become so outdated that you'll be forced to learn it all then when you're trying to change job. And it will have been a lot easier to learn on the job all those years before :)
A few months ago I heard Bjarne Stroustrup give a talk titled 50 years of C++. Admittedly, I'm not a C++ programmer, but it seemed to me that he certainly doesn't think 0x is a new language!
Whether or not we can consider it a "new language", I think that's semantics. It doesn't make a difference. It's backwards compatible with our current C++ code, and it's a better language. Whether or not we consider it "the same language" doesn't matter.
About learning the language, remember that a lot of the new features are there to make the language easier to learn and use. Most of the features that add complexity are intended for library developers only. They can use these new features to make better, more efficient, and easier to use libraries, that you can then use without knowing about the features. Several of the changes actually simplify and generalize existing features, making them easier for newcomers to learn.
It is a big update, yes, but it is guided by a decade of experience with the current C++ standard. Every change is there because experience has shown that it is needed. In fact, the committee is being extremely cautious and conservative, and have refused a huge number of other language improvements. What is added here is only the fundamentals that 1) everyone could agree on, and 2) could be specified in time, without delaying the new standard.
It is not simply a few language designers sitting down and brainstorming new features they'd like to try.
Concepts and Concept Maps are going to greatly increase the grokability of template frameworks. If you've ever poured over the Boost source you'll know what I mean. You're constantly going from source to docs because the language just doesn't have the facilities to express template concepts. Hopefully Concepts + Duck Typing will give us the best of both worlds whereby entry points to template libraries can explicitly declare requirements but still have the freedom that Duck Typing provides when writing generic code.
There are lots of good things in C++0x, but they're mostly evolutionary changes that refine or extend existing ideas. I don't think it's different enough to justify calling it a "new language".