Tuesday, November 1, 2016

C++ tips, 2016 Week 43 (24-Oct - 30-Oct-2016)

This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you dont have it in your company start it. 
List of all weekly posts can be found here.

1. Infographics: Operation Costs in CPU Clock Cycles

Taken from the blog post of 'No Bugs' Hare



More explanation can be found in the original post. It should be noted that in general you dont need to be extremely aware of what executes in how many CPU cycles but to have a idea of what is the cost of the different classes of operations or "to have mechanical sympathy".

2. Template metaprogramming functions 

In C++ template metaprogramming (treating types as objects), a template metaprogramming "function" (or metafunction) usually looks something like this:
template_meta_funct<parameter1, parameter2, parameter3, parameter4>::return_value
where template_meta_funct (which is a template class or struct) is the metafunction name, parameter1-4 are the types that are the input parameters and return_value is ... the return value (Note! you can have many return values).

Because the metafunctions depends only on the input parameters and the classes are immutable (the world does not change during evaluation of the return parameters - everything is done at compile time) those functions are pure functions. And that is why template metaprogramming is considered functional programming. Kind of :)

Extremely simple example:

a metafunction that takes a type as input parameter and returns const & to that type:

template<class T>
struct as_constref
{
using type = const T&;
};

usage:
using cref = as_constref<float>::type;
cref takes the return value type which evaluates at compile time to const float& 

Based on what I've read in the free book Practical C++ Metaprogramming

3. Tag dispatching 

Tag dispatching is a technique of selecting different implementations based on a class trait. 

A typical example is the implementation of std::advance:

template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );

The function will chose different implementation based on the InputIt iterator_traits. A simple implementation will be something like this 

template<class Iterator, class Distance> 
void advance(Iterator& it, Distance n, std::random_access_iterator_tag) 
{ 
   it += n; 
} 
 
template<class Iterator, class Distance> 
void advance_impl(Iterator& it, Distance n, std::bidirectional_iterator_tag) 
{ 
   if(n < 0) { 
      while(n++) --it; 
   } else { 
      while(n--) ++it; 
   } 
} 
 
template<class Iterator, class Distance> 
void advance_impl(Iterator& it, Distance n, std::input_iterator_tag) 
{ 
   assert(n >= 0); 
   while(n--) ++it; 
} 
 
template< class Iterator, class Distance > 
void advance( Iterator& it, Distance n ) 
{ 
   advance_impl(it, n, 
                /* Tag Dispatching */ 
                typename std::iterator_traits<Iterator>::iterator_category()); 
}

4. Structured bindings

From C++17 we can use structured bindings:
auto [x, y, z] = expression;
where the expression can be one of built-in array, std::tuple, std::array, std:: pair or C-style struct:

tuple<T1, T2, T3> f(); 
auto [x, y, z] = f(); // types are: T1, T2, T3   
 
struct mystruct { int i; string s; double d; }; 
mystruct s = { 1, "xyzzy"s, 3.14 }; 
auto [x, y, z] = s; // types are: int, string, double 
 
auto tuple = std::make_tuple(1, 'a', 2.3); 
auto& [ i, c, d ] = tuple; 
 
for (auto&& [first,second] : mymap) { 
  // use first and second 
}

Taken from my post C++'s Syntactic sugars

5. Features removed from C++17 

That's right. The rumors are true! The C++ Standards Committee is in fact removing things from C++! And here they are - the features that are removed from C++ in the incoming standard (C++17). Removed as in "it wont compile if you try to use them"


 (Most likely I missed something)

No comments:

Post a Comment