The addition, err, redefinition of the auto keyword in C++11 was a great move to reduce code verbosity during the definition of local variables:
In addition to this convenient usage, employing auto in conjunction with the new (and initially weird) function-trailing-return-type syntax is useful for defining function templates that manipulate multiple parameterized types (see the third entry in the list of function definitions below).
In the upcoming C++14 standard, auto will also become useful for defining normal, run-of-the-mill, non-template functions. As the fourth entry below illustrates, we’ll be able to use auto in function definitions without having to use the funky function-trailing-return-type syntax (see the useless, but valid, second entry in the list).
For a more in depth treatment of C++11′s automatic type deduction capability, check out Herb Sutter’s masterful post on the new AAA (Almost Always Auto) idiom.
Since I have the privilege of using C++11/14 on my current project, I’ve been using the new language idioms as fast as I can discover and learn them. For example, instead of writing risky, exception-unsafe, naked “new“, code like this:
I’ve been writing code like this instead:
By using std::unique_ptr instead of a naked pointer, I don’t have to veer away from the local code I’m writing to write matching delete statements in destructors or in catch() exception clauses to prevent inadvertent memory leaks.
I could’ve used a std::shared_ptr (which can be copied instead of “moved“) in place of the std::unique_ptr, but std::shared_ptr is required to maintain a fatter internal state in the form of strong and weak owner counters. Unless I really need shared ownership of a dynamically allocated object, which I haven’t so far, I stick to the slimmer and more performant std::unique_ptr.
When I first wrote the std::unique_ptr code above, I was concerned that using the std::move() function to transfer encapsulated memory ownership into the safeTgtList vector would add some runtime overhead to the code (relative to the C++98/03 style of simply copying the naked pointer into the scaryTgtList vector). It is, after all, a function, so I thought it must insert some code into my own code.
However, after digging a little deeper into my concern, I discovered (via Stroustrup, Sutter, and Meyers) that std::move() adds zero runtime overhead to the code. Its use is equivalent to performing a static_cast on its argument – which is evaluated at compile time.
As Scott Meyers stated at GoingNative13, std::move() doesn’t really move anything. It simply prepares for a subsequent real move by casting its argument from an lvalue to an rvalue – which is required for movement of an object’s innards. In the previous code, the move is actually performed within the std::vector::emplace_back() function.
Quoting Scott Meyers: “think of std::move() as an rvalue_cast“. I’m not sure why the ISO C++ committee didn’t define a new rvalue_cast keyword instead of std::move() to drive home the point that no runtime overhead is imposed, but I’d speculate that the issue was debated. Perhaps they thought rvalue_cast was too technical a term for most users?
As I said early in the post, the code example is “like” the code I’ve been writing. The real code that triggered this post is as shown here:
Since each “entry” CfarDetState object must be uniquely intialized form it’s associated CfarCrossing object, I can’t simply insert estd::make_unique<CfarDetState>() into the emplace_back() function. All of the members of each “entry” must be initialized first. Regardless of whether I use emplace_back() or push_back(), std::move(entry) must be used as the argument of the chosen function.
Herb Sutter is by far the biggest cheerleader for the C++ programming language – even more so than the language’s soft spoken creator, Bjarne Stroustrup. Herb speaks with such enthusiasm and optimism that it’s infectious.
In his talk at the recently concluded GoingNative2013 C++ conference, Herb presented this slide to convey the structure of the ISO C++ Working Group 21 (WG21):
On the left, we have the language core and language evolution working groups. On the right, we have the standard library working group.
But wait! That was the organizational structure as of 18 months ago. As of now, we have this decomposition:
As you can see, there’s a lot of volunteer effort being applied to the evolution of the language – especially in the domain of libraries. In fact, most of the core language features on the left side exist to support the development of the upcoming libraries on the right.
In addition to the forthcoming minor 2014 release of C++, which adds a handful of new features and fixes some bugs/omissions from C++11, the next major release is slated for 2017. Of course, we won’t get all of the features and libraries enumerated on the slide, but the future looks bright for C++.
The biggest challenge for Herb et al will be to ensure the conceptual integrity of the language as a whole remains intact in spite of the ambitious growth plan. The faster the growth, the higher the chance of the wheels falling off the bus.
“The entire system also must have conceptual integrity, and that requires a system architect to design it all, from the top down.” – Fred Brooks
“Who advocates … for the product itself—its conceptual integrity, its efficiency, its economy, its robustness? Often, no one.” – Fred Brooks
I’m not a fan of committees in general, but in this specific case I’m confident that Herb, Bjarne, and their fellow WG21 friends can pull it off. I think they did a great job on C++11 and I think they’ll perform just as admirably in hatching future C++ releases.
Relatively recently, I participated in a debate with a peer regarding the sacredness of the Single Entry / Single Exit (SE/SE) “rule” of programming. I wish I had this eloquent Herb Sutter treatise on hand when it occurred:
Woot! Now that I’ve stashed the case against SE/SE nazi “enforcement” on this blawg, I’m armed and ready to confront the next brainwashed purist on the matter.
On my current project, we’re joyfully using C++11 to write our computationally-dense target processing software. We’ve found that std::shared_ptr and std::unique_ptr are extremely useful classes for avoiding dreaded memory leaks. However, I find it mildly irritating that there is no std::make_unique to complement std::make_shared. It’s great that std::make_unique will be included in the C++14 standard, but whenever we use a std::unique_ptr we gotta include a fugly “new” in our C++11 code until then:
But wait! I stumbled across this helpful Herb Sutter slide:
A variadic function template that uses perfect forwarding. It’s outta my league, but….. Whoo Hoo! I’m gonna add this sucker to our platform library and start using it ASAP.
At Microsoft’s Build 2012 conference, ISO C++ chairman Herb Sutter introduced the new isocpp.org web site. On the site, you can download a draft version of Chapter 2 from Bjarne Stroustrup‘s upcoming “The C++ Programming Language, 4th Edition“. As I read the chapter and took “the tour“, I noted the new C++11 features that Bjarne used in his graceful narrative. Here they are:
auto, intializer lists, range-for loops, constexpr, enum class, nullptr, static_assert.
Since I’m a big Stroustrup and C++ fan, I just wanted to pass along this tidbit of info to the C++ programmers that happen to stumble upon this blog.