Articles & Books

New updates of CppHints.com, service of recommendations on C++ programming from PVS-Studio team

New updates of C++Hints, service of recommendations on C++ programming

Changes in CppHints.com

by PVS-Studio Team

We got a lot of positive feedback from our readers and continue developing the C++Hints project. We have also answered two requests, that we saw quite often in the letters:

By this moment we have published the following articles:

An introduction to C++'s SFINAE concept -- Jean Guegant

Jean Guegant describes in a very detailed way different implementation stategies of compile-time introspection of a class member for C++98, C++11 and C++14.

An introduction to C++'s SFINAE concept: compile-time introspection of a class member

by Jean Guegant

From the article:

As a C++ enthusiast, I usually follow the annual C++ conference cppconf or at least try to keep myself up-to-date with the major events that happen there. One way to catch up, if you can't afford a plane ticket or the ticket, is to follow the youtube channel dedicated to this conference. This year, I was impressed by Louis Dionne talk entitled "C++ Metaprogramming: A Paradigm Shift". One feature called is_valid that can be found in Louis's Boost.Hana library particulary caught my attention. This genious is_valid function heavily rely on an even more "magic" C++ programming technique coined with the term SFINAE discovered at the end of the previous century. If this acronym doesn't speak to you, don't be scared, we are going to dive straight in the subject.

Random Acts of Optimization --Tony Albrecht

Discussion regarding systematic approach to go about optimization of logic.

Random Acts of Optimization

by Tony Albrecht

From the article:

The three stages mentioned here, while seemingly obvious, are all too often overlooked when programmers seek to optimize. Just to reiterate:

    1. Identification: profile the application and identify the worst performing parts.
    2. Comprehension: understand what the code is trying to achieve and why it is slow.
    3. Iteration: change the code based on step 2 and then re-profile. Repeat until fast enough.

The solution above is not the fastest possible version, but it is a step in the right direction—the safest path to performance gains is via iterative improvements.

Using Variadic Templates cleanly--Florian Weber

Variadics are even more easy to use than we tought:

Using Variadic Templates cleanly

by Florian Weber

From the article:

When one comes across examples for variadic templates, almost always recursion is used to achieve almost everything, for example like this:

// We are lucky: the author correctly used zero
// arguments instead of one as the base-case,
// thereby avoiding code-duplication:
inline void print_to_stream(std::ostream&) {}

template<typename Head, typename...Tail>
void print_to_stream(std::ostream& stream, const Head& h, const Tail&... t) {
  stream << h;
  print_to_stream(stream, t...);
}

In this article we will see what better alternatives for this rather clumsy hack exist and see how we can write a better version with less code...

Trip report: C++ standards meeting in Kona, October 2015 -- Stephan T. Lavavej

The fall ISO C++ standards meeting concluded less than 24 hours ago, and our own STL (the person, not the library) has posted the first trip report to Reddit. It was a very successful meeting with considerable progress.

C++17 Progress Update! (Oct 2015)

by Stephan T. Lavavej (aka STL)

Note that this report is focused on an overview of what reached full committee approval, with an emphasis on library features. Important milestones were also achieved to progress other major topics, including modules, contracts, and variant that we hope will reach formal full committee approval at the next meeting or two, and these topics will no doubt be covered in other people's trip reports and commentaries as well.

More than you need--Andrzej KrzemieĊ„ski

Some thoughts about what the standard provides by default:

More than you need

by Andrzej Krzemieński

From the article:

The classes you design can do more (in terms of allowed operations) than what you could figure out from just looking at their member function declarations. The C++ Standard defines a number of cases where certain expressions involving your type are valid, even though there are no corresponding member function declarations. Sometimes this is just what you need; but sometimes the additional operations you never asked for can have grave negative impact on your program correctness...

 

Lambda hackery: Overloading, SFINAE and copyrights -- Nikos Athanasiou

Lambdas are often miscalled "functions"; learn how to implement some "function only" features in the article:

Lambda hackery: Overloading, SFINAE and copyrights

by Nikos Athanasiou

From the article:

If we think of lambdas as functions we’d might make an attempt to overload them. This attempt is easy to rebut by stating that lambdas are closures ie runtime objects and well … objects, even callable ones, do not overload! (...) The closest thing to a lambda that can overload is its function call operator, so you might already had your “aha!” moment by now. If not, here it is ...

Quick Q: What container should I use to reduce fragmentation caused by lots of small allocations?

Quick A: The only one matching the requirements is a std::deque, but it might be worth to consider using a memory pool.

Recently on SO:

What C++ std container should I use to reduce fragmentation caused by lots of small allocations?

Since you're asking specifically for a standard container, std::deque is the most promising option given your requirements. As long as you only add elements, the existing ones are not relocated, and references/pointers (but not iterators) remain valid. When removing elements, you may however need to leave gaps or swap the element to remove with the last element.

std::vector is not stable, and std::list, std::forward_list as well as all the associative containers are fragmented.

Looking at Boost.Container, you have additional options, however with other trade-offs:

boost::flat_map provides contiguous storage (like std::vector), but with it the stability problem
boost::stable_vector offers element stability at the cost of contiguity.
Alternatively, you can have a look at pool allocators (like Boost.Pool). They provide low fragmentation and fast allocation, and the container in front of it can still be used like a normal container.