Scott Meyers presented three guidelines from his upcoming new edition of Effective C++:
- Understand std::move and std::forward
- Declare functions noexcept whenever possible
- Make std::threads unjoinable on all paths
The advice on std::move and std::forward echoes thoughts from Scott’s earlier presentation on Universal References. This time, he also talks about efficiency and points out that some standard library methods (such as std::vector::push_back) won’t move unless it can do so using noexcept methods. This is the motivation for the second guideline to use noexcept whenever possible on these key methods (move operators and swap).
The guideline on std::threads harks back to the ongoing discussions in the standards committee – when a joinable (“running”) thread is destroyed, should it block/detach/terminate. Scott advises to use RAII to force the behaviour that you want, and presents a simple class for that purpose.
I’ve watched a few of the Going Native 2013 videos now and, whilst I was impressed by Herb Sutter’s games written in Cinder, I particularly like the slide and gather algorithms demonstrated by Sean Parent in his C++ seasoning presentation:
auto slide(Iter begin, Iter end, Iter target) -> std::pair<Iter,Iter>
if (target < begin) return std::make_pair( target, std::rotate(target, begin, end) );
if (end < target) return std::make_pair( std::rotate( begin, end, target ), target );
return std::make_pair( begin, end );
template<typename Iter, typename Pred>
auto gather(Iter begin, Iter end, Iter target, Pred predicate) -> std::pair<Iter,Iter>
auto start = std::stable_partition( begin, target, std::not1(predicate) );
auto finish = std::stable_partition( target, end, predicate );
return std::make_pair(start, finish);
Whilst I haven’t used std::rotate or std::stable_partition, I’m sure to use these two algorithms built on top of them, probably because their behaviour is so much easier to describe.
Scott Meyers posted a video of his Universal References presentation from C++ and Beyond 2012. There’s also an article on the subject in the ACCU magazine Overload Issue 111, but I found the video much clearer (and more entertaining).
Meyers coined the term ‘Universal References’ for instances where the type of a variable or parameter is declared T&& and where T is a deduced type. It may look like an rvalue-reference, but it can also match lvalue-references:
so it’s usually a mistake to overload on both T&& and const T& in a template function. Another key point is that, whereas an overload with an rvalue-reference would call std::move (e.g. a move constructor where T is not deduced), an overload with a universal-reference should call std::forward (because you don’t yet know if it’s an rvalue- or lvalue-reference):
He also summarises the reference-collapsing rules as “lvalue-references are infectious”, a handy mnemonic from Stephan T. Lavavej.
Andrei Alexandrescu gave this talk on optimization tips for C++. He claims you should aim to:
- Measure performance against a baseline
- Choose algorithms that use the least heavyweight operations
- Reduce array writes
The slides are also available.
Measuring gives you a leg up on experts who don’t need to measure
He also presents a handy ordering of different integral/floating point operations in terms of cost. The techniques (which he has internalised to give a gut feel of whether some improvement will produce a speed-up) are illustrated with a classic interview question (convert an integer to ascii) that is heavily used at Facebook.
The underlying message of this presentation is that the cost of one engineer spending time producing some pretty esoteric code with massive performance benefits is more than outweighed by the savings in terms of data centre costs (due to improved speed, you can scale back spend on servers).
TechCrunch broadcast an interview with Tactus, the company behind an innovation to bring transient pop-up buttons to flat screen devises.
Herb Sutter has published his C++ and Beyond talk on Const and Mutable in C++ 11.