Unknown's avatar

Posts by Marius Bancila

Software architect, author, speaker, Microsoft MVP Developer Technologies

Binary literals and digit separators

The C++14 standard provides two new small features to the language: binary literals and digit separators. They are already available in Clang 3.4 and GCC 4.9 and now Visual Studio 2015 RC has implemented them. They may not be something you can’t live without, but sometimes it’s convenient to have them. Let’s have a look.

In C++ it was possible to input integer literals in several bases: decimal, hexadecimal and octal. However, the binary base has been omitted (though other languages supported that). With C++14 binary is also supported and binary literals are introduced with the prefix 0b or 0B.

int i1 = 42;
int i2 = 052;
int i3 = 0x2A;
int i4 = 0b101010;

Binary literals can be used anywhere integral literals are expected.

enum class flags
{
   read     = 0b0001,
   write    = 0b0010,
   execute  = 0b0100
};

What if you had to write large literals such as 0b101111000110000101001110, which is the binary representation of decimal 12345678? Sometimes it is convenient to separate groups of digits for more human readability.

C++14 defines the single quotation mark (') as a digit separator in integral and floating point literals. So the binary literal 0b101111000110000101001110 can be expressed in several ways:

int n1 = 0b1011'1100'0110'0001'0100'1110;
int n2 = 0b10111100'01100001'01001110;

or maybe in hexadecimal:

int n3 = 0xbc'61'4e;

The position of the single quotation marks in the integral or floating point literals is irrelevant, they are simply ignored when determining the value of the literal. All the following are equivalent (but probably only the first and the last make sense).

int n1 = 12345;
int n2 = 1'2'3'4'5;
int n3 = 1'23'4'5;
int n4 = 1'234'5;
int n5 = 12'3'45;
int n6 = 12'345;

C++ Gems: ref-qualifiers

VC++ 2014 is finally supporting ref-qualifiers, maybe a lesser know feature in C++11 that goes hand in hand with rvalue references. In this post I will explain what ref-qualifiers are and why they are important.

But before talking about ref-qualifiers let’s talk about the well known cv-qualifiers.

cv-qualifiers

Let’s take the following example of a type foo that has two overloaded methods, one const and one not const.

struct foo
{
   void test()       { std::cout << "test" << std::endl; }
   void test() const { std::cout << "test const" << std::endl; }
};

The following code prints either “test” or “test const” depending on whether the object function test() is called on is const or not.

foo f1;
f1.test();     // prints "test"

foo const f2;
f2.test();     // prints "test const"

foo().test();  // prints "test"

Notice that the const/volatile specification is not a constrain on the function, but on the implied this parameter. A const function can freely modify state or call non-const methods, but not state or non-const methods that belong to the object referred by this.

Let’s consider a second example where he have a Widget contained within a bar. The bar has methods to return the internal state. If the object is const, the overload resolution picks the const method, if it is non-const it picks the non-const method.

struct Widget
{
   Widget(std::string const & name) : name(name) {};
   Widget(Widget const & w)   { std::cout << "copy" << std::endl; name = w.name; }
   Widget(Widget&& w)         { std::cout << "move" << std::endl; name = std::move(w.name); }

private:
   std::string name;
};

struct bar
{   
   Widget&       data()          { return _widget; }
   Widget const& data() const    { return _widget; }

private:
   Widget _widget{ "bar" };
};

bar b1;
auto w1 = b1.data();    // prints copy

bar const b2;
auto w2 = b2.data();    // prints copy

auto w3 = bar().data(); // prints copy

The problem with this code is that in all cases the Widget was copied even though in the last example the Widget owner was an rvalue reference and the object could have been moved.

To fix this problem we can add a new method that returns an rvalue reference. However, the problem now is that we cannot have two overloaded methods, one that returns a lvalue reference and one that returns an rvalue reference. So the best we could do is this:

struct bar
{   
   Widget const & data() const   { return _widget; }
   Widget&&       data()         { return std::move(_widget); }

private:
   Widget _widget{ "bar" };
};

bar b1;
auto w1 = b1.data();    // prints move

bar const b2;
auto w2 = b2.data();    // prints copy

auto w3 = bar().data(); // prints move

This fixed the 3rd case with the rvalue reference, but it broke the first object. After calling b1.data() the Widget from b1 was moved to w1.

What’s the solution?

Enter ref-qualifiers

ref-qualifiers are a way to help the compiler decide which function to call when the object is an lvalue or an rvalue. Since the object is passed as an implicit pointer type parameter to the function (pointer this) the ref-qualifiers have been also referred as “rvalue reference for *this”.

ref-qualifiers are specified with & for lvalues and && for rvalues at the end of the function signature after the cv-qualifiers.

struct bar
{   
   Widget&        data() &         { return _widget; }
   Widget const & data() const &   { return _widget; }
   Widget&&       data() &&        { return std::move(_widget); }

private:
   Widget _widget{ "bar" };
};

The following code now prints “copy”, “copy”, “move” as expected.

bar b1;
auto w1 = b1.data();    // prints copy

bar const b2;
auto w2 = b2.data();    // prints copy

auto w3 = bar().data(); // prints move

One important thing to note is that you cannot mix ref-qualifier and non-ref-qualifier overloads. You must decided over one or another set of overloads. The following is illegal:

Widget&        data()           { return _widget; } // no ref-qualifier
Widget const & data() const     { return _widget; } // no ref-qualifier
Widget&&       data() &&        { return std::move(_widget); } // ref-qualifier

The ref-qualifiers help avoiding unnecessary calls/operations on rvalue references which is helpful when may involve large objects. But they are also helpful to avoid making coding mistakes. Here is an example. Consider the following type:

struct foo
{
   foo(int const value = 0) :value(value)
   {}

   foo& operator=(foo const & other)
   {
      this->value = other.value;
      return *this;
   }

   operator int() const { return value; }

private:
   int value;
};

foo get_foo()
{
   return foo(13);
}

You can write things like this:

foo() = 42;

if (get_foo() = 42)
{
}

Probably the first example is a little bit silly, you don’t do that kind of mistake in real life, but it’s still legal code that executes, and is not right because there’s an rvalue reference on the left side of the assignment operator. The second example is definitely a much realistic example. Sometimes we just type = instead of == in conditional expressions and what the code will do is assigning 42 to temporary, instead of testing their equality.

If we changed the signature of foo’s operator= to include a ref-qualifier (as shown below) the compiler would flag immediately both examples above as errors:

foo& operator=(foo const & other) & 
{
    // ...
}

VC++ 2014 now flags the following error:

error C2678: binary ‘=’: no operator found which takes a left-hand operand of type ‘foo’ (or there is no acceptable conversion)

Compiler support

See also

User defined literals

The C++ language defines various built-in literals (numerical, character, string, boolean and pointer) and a series of prefixes and suffixes to specify some of them. The suffix or prefix is part of the literal.

auto b = true;     // boolean
auto s = "sample"; // const char[7]
auto i = 128;      // int
auto d = 128.0;    // double
auto p = nullptr;  // nullptr_t

// with prefixes
auto w = L"text";  // const wchar_t[5]
auto h = 0xBAD;    // int (in hexadecimal representation)

// with suffixes
auto a = 128u;     // unsigned int
auto l = 128l;     // signed long
auto f = 128.0f;   // float

The C++11 standard introduced the possibility to create user-defined literals, that are basically built-in type literals (integer, float, char or string) followed by a used-defined suffix. User-defined literals enable the creation of new objects based on the built-in literal value and the applied user-defined suffix.

auto temp = 77_fah;       // 77 Fahrenheit degrees = 25 Celsius degrees
auto size = 1_KB;         // 1 kilobyte = 1024 bytes
auto emp  = "marius"_dev; // a user defined type Developer

A bit of theory

A user-defined literal is treated as a call to a literal operator or a literal operator template. User-defined literals have two forms:

  • raw: a sequence of characters; the literal 0xBAD is in raw form is ‘0’, ‘x’, ‘B’, ‘A’, ‘D’
  • cooked: is the compiler interpreted type of the sequence of characters; the literal 0xBAD is the integer 2898 in cooked form.

User-defined literals:

  • support only the suffix form; defining prefixes is not possible;
  • begin with a underscore (‘_’); all suffixes that begin with any other character except underscore are reserved by the standard;
  • can be extended in both raw and cooked form; the exception is represented by strings that can only be extended in the cooked form

Cooked literals

The literal operator called for a cooked literal has following form:

OutputType operator "" _suffix(InputType);

Only several input types are allowed:

  • for integral literals (decimal, octal, hexadecimal or binary) the type is unsigned long long (the reason for unsigned is that the sign is not part of a numeric literal, but is in fact a unary operator applied to the numerical value).
    OutputType operator "" _suffix(unsigned long long);
    
  • for floating point types the type is long double:
    OutputType operator "" _suffix(long double);
    
  • for characters the type is char, wchar_t, char16_t or char32_t:
    OutputType operator "" _suffix(char);
    OutputType operator "" _suffix(wchar_t);
    OutputType operator "" _suffix(char16_t);
    OutputType operator "" _suffix(char32_t);
    
  • for strings the type is char const *, wchar_t const *, char16_t const * or char32_t const *:
    OutputType operator "" _suffix(char const *, std::size_t);
    OutputType operator "" _suffix(wchar_t const *, std::size_t);
    OutputType operator "" _suffix(char16_t const *, std::size_t);
    OutputType operator "" _suffix(char32_t const *, std::size_t);
    

Raw literals

Raw literals are supported only for integral and floating point types. The literal operator called for a cooked literal has following form (notice that the operator does not take a second parameter to indicate the size, the string is null-terminated):

OutputType operator "" _suffix(const char*);

Parsing this array of characters may involve loops, variable declaration, function calls, etc. As a result this form of the literal operator cannot be constexpr, which means it cannot be evaluated at compile time.

An alternative way of processing raw literals is with a literal operator variadic template. The purpose of a variadic template literal operator is to make the literal transformation at compile time. The form of the literal operator template is:

template<char...> OutputType operator "" _tuffix();

A bit of practice

Let’s take the following example where we declare a buffer of 4 KB.

std::array<unsigned char, 4_KB> buffer;

This is identical to the following declaration (you’d usually expect)

std::array<unsigned char, 4096> buffer;

It is made possible by the existence of a literal operator with the following form:

constexpr size_t operator "" _KB(unsigned long long size)
{
   return static_cast<size_t>(size * 1024);
}

If the literal operator was not a constexpr then the compiler would trigger an error when declaring the buffer variable, because the size of the array must be known at compile time. You’d still be able to use the user-defined literal but in runtime contexts, such as sizing a vector.

std::vector<unsigned char> buffer(4_KB);

In the next example we define a user-defined literal for expressing temperatures in Fahrenheit degrees. Supposing the Celsius degrees are the norm, we can write sometime like this:

constexpr long double operator"" _fah(long double const degrees)
{
   return (degrees - 32.0) / 1.8;
}

and use it like in the following example:

auto threshold = 77.0_fah;
auto temp = 0.0;
std::cout << "Input temperature (in Celsius):";
std::cin >> temp;

std::cout << (temp < threshold ? "cold" : "warm") << std::endl;

The return type of the literal operator can be any type; it does not have to be a built-in type like in the previous examples. Given the following hierarchy of classes we can create user-defined literals that enable the creation of developer and quality assurer objects:

class Employee
{
   std::string name;
public:
   Employee(std::string const & name) :name(name){}
   std::string getName() const { return name; }
};

class Developer : public Employee
{
public:
   using Employee::Employee;
};

class QualityAssurer : public Employee
{
public:
   using Employee::Employee;
};

Developer operator "" _dev(char const * text, std::size_t const size)
{
   return Developer(std::string(text, text + size));
}

QualityAssurer operator "" _qa(char const * text, std::size_t const size)
{
   return QualityAssurer(std::string(text, text + size));
}

int main()
{
   auto d = "marius"_dev;
   auto q = "john"_qa;
   std::cout << d.getName() << std::endl;
   std::cout << q.getName() << std::endl;

   return 0;
}

In the next example we want to express latitudes, such as 66°33’39”N (the Arctic Circle). (Notice that the following types and just some simple implementations for demo purposes only).

class GeoCoordinate
{
protected:
   double degrees;
   double minutes;
   double seconds;
public:
   constexpr GeoCoordinate(double const degrees, double const minutes, double const seconds)
      :degrees(degrees), minutes(minutes), seconds(seconds)
   {}

   GeoCoordinate& operator+=(GeoCoordinate const & other)
   {
      seconds += other.seconds;
      minutes += other.minutes;
      degrees += other.degrees;

      return *this;
   }

   friend GeoCoordinate operator+(GeoCoordinate lhs, GeoCoordinate const & rhs)
   {
      return lhs += rhs;
   }

   double get_degrees() const { return degrees; }
   double get_minutes() const { return minutes; }
   double get_seconds() const { return seconds; }
};

enum class LatitudeDirection
{
   Undefined,
   North,
   South,
};

class Latitude : public GeoCoordinate
{
   LatitudeDirection direction;
public:
   constexpr Latitude(double const degree, double const minutes, double const seconds, LatitudeDirection const dir = LatitudeDirection::Undefined)
      :GeoCoordinate(degree, minutes, seconds), direction(dir)
   {}

   Latitude& operator+=(Latitude const & other)
   {
      if (direction == other.direction || direction == LatitudeDirection::Undefined || other.direction == LatitudeDirection::Undefined)
      {
         seconds += other.seconds;
         minutes += other.minutes;
         degrees += other.degrees;

         if (direction == LatitudeDirection::Undefined)
         {
            direction = other.direction;
         }
      }
      else
         throw std::exception("Invalid latitude direction");

      return *this;
   }

   friend Latitude operator+(Latitude lhs, Latitude const & rhs)
   {
      return lhs += rhs;
   }

   friend Latitude operator+(Latitude lhs, LatitudeDirection dir)
   {
      if (lhs.direction != LatitudeDirection::Undefined &&
         lhs.direction != dir)
         throw std::exception("Invalid latitude direction");

      Latitude l = lhs;
      l.direction = dir;
      return l;
   }
};

Latitude operator+(GeoCoordinate lhs, LatitudeDirection dir)
{
   return Latitude(lhs.get_degrees(), lhs.get_minutes(), lhs.get_seconds(), dir);
}

With this in place we can create objects like this:

>
auto g1 = GeoCoordinate(66, 0, 0);
auto g2 = GeoCoordinate(0, 33, 0);
auto g3 = GeoCoordinate(0, 0, 39);
auto g4 = g1 + g2 + g3;
auto g5 = GeoCoordinate(66, 0, 0) + GeoCoordinate(0, 33, 0) + GeoCoordinate(0, 0, 39);

auto l1 = Latitude(66, 0, 0, LatitudeDirection::North);
auto l2 = Latitude(0, 33, 0);
auto l3 = Latitude(0, 0, 39);
auto l4 = l1 + l2 + l3;

auto l5 = Latitude(66, 0, 0, LatitudeDirection::North) + Latitude(0, 33, 0) + Latitude(0, 0, 39);
auto l6 = Latitude(66, 0, 0) + Latitude(0, 33, 0) + Latitude(0, 0, 39) + LatitudeDirection::North;
auto l7 = GeoCoordinate(66, 0, 0) + GeoCoordinate(0, 33, 0) + GeoCoordinate(0, 0, 39) + LatitudeDirection::North;

Values like Latitude(66, 0, 0) are not very intuitive. Even though it’s more verbose it may be more desirable to be able to create objects like this:

auto lat = deg(66) + min(33) + sec(39) + LatitudeDirection::North;

That is possible if we define deg(), min() and sec() as following:

constexpr GeoCoordinate deg(double value)
{
   return GeoCoordinate(value, 0, 0);
}

constexpr GeoCoordinate min(double value)
{
   return GeoCoordinate(0, value, 0);
}

constexpr GeoCoordinate sec(double value)
{
   return GeoCoordinate(0, 0, value);
}

User-defined literals makes is more simple and more natural. By transforming the above functions into literal operators we can simplify the syntax.

constexpr GeoCoordinate operator "" _deg(long double value)
{
   return GeoCoordinate(value, 0, 0);
}

constexpr GeoCoordinate operator "" _min(long double value)
{
   return GeoCoordinate(0, value, 0);
}

constexpr GeoCoordinate operator "" _sec(long double value)
{
   return GeoCoordinate(0, 0, value);
}

As a result we can now create latitudes like this:

auto lat = 66.0_deg + 33.0_min + 39.0_sec + LatitudeDirection::North;

It should be very simple to develop this to support longitudes. You don’t have to add more literal operators, just the Longitude type and the appropriate overloaded operators for it.

Standard user-defined literals

C++14 defines several literal operators:

  • operator""if, operator""i and operator""il for creating a std::complex value
    #include <complex>
    
    int main()
    {
       using namespace std::literals::complex_literals;
       std::complex<double> c = 1.0 + 2i;
    }
    
  • operator""h, operator""min, operator""s, operator""ms, operator""us, operator""ns for creating a std::chrono::duration value
    #include <chrono>
    
    int main()
    {
       using namespace std::literals::chrono_literals;
       auto timer = 1h + 30min + 30s; // duration 01:30:30
    }

    This is equivalent to the following (longer) form in C++11:

    auto timer = std::chrono::hours(1) + std::chrono::minutes(30) + std::chrono::seconds(30);
    
  • operator""s for converting a character array literal to a std::basic_string
    int main()
    {
       using namespace std::string_literals;
       std::string s1 = "text\0";  // s1 = "text"
       std::string s2 = "text\0"s; // s2 = "text\0"
    }
    

Notice that all these literal operators are defined in separate namespaces that you have to use.

References

Compiler support

User defined literals are supported by major compilers starting with the following version:

See also:

Five new algorithms to C++11 that you should know about

C++11 added a bunch of new general purpose algorithms to the <algorithm> header. In this article we will look at five of them that C++ developers should know about.

all_of, any_of and none_of

These are actually three, not just a single algorithm, all_of, any_of, none_of, but they are very similar. They check if the supplied unary predicate return true for all, any or no element in a range.

Here are several examples:

int numbers[] = {1, 2, 42, 7, 0};

auto is_positive = [](int const n){return n >= 0;};
std::cout << std::boolalpha 
          << std::all_of(std::begin(numbers), std::end(numbers), is_positive)
          << std::endl;

auto is_zero = [](int const n) {return n == 0;};
std::cout << std::boolalpha
          << std::any_of(std::begin(numbers), std::end(numbers), is_zero)
          << std::endl;

std::vector<std::string> words = {"to", "be", "or", "not"};

auto is_empty = [](std::string const & s) {return s.empty();};
std::cout << std::boolalpha
          << std::none_of(std::begin(words), std::end(words), is_empty)
          << std::endl;

is_sorted and is_sorted_until

The first algorithm, is_sorted, checks if the elements of the range are sorted ascending. There are two overloads of the function, the first uses operator< and the second takes a comparison function (that return true if the first element is less than the second) and uses that for comparing the elements in the range.

int numbers[] = {1, 2, 42, 7, 0};

std::cout << std::boolalpha
          << std::is_sorted(std::begin(numbers), std::end(numbers))
          << std::endl;


std::vector<std::string> words = {"to", "be", "or", "not"};

auto smaller_length = [](std::string const & first, std::string const & second) 
                      {
                         return first.length() < second.length();
                      };
std::cout << std::boolalpha
          << std::is_sorted(std::begin(words), std::end(words), smaller_length)
          << std::endl;

The second algorithm, is_sorted_until, is similar in that it checks that the elements of a range are sorted ascending. However, the function does not return a boolean value, but an iterator to the upper bound of the largest sorted sub-range (starting at the beginning of the examined range), i.e. the next beyond the last sorted element. There are two overloads, the first uses operator< and the second takes a comparison function, just like is_sorted does.

int numbers[] = {1, 2, 42, 7, 0};

auto last = std::is_sorted_until(std::begin(numbers), std::end(numbers));
std::cout << "upper bound = " << *(last-1) << std::endl;
std::cout << "sort size   = " << std::distance(std::begin(numbers), last) << std::endl;

The output for this sample is:

upper bound = 42
sort size   = 3

is_partitioned

Algorithm is_partitioned checks whether a range is partitioned, i.e. sorted according to the supplied unary predicate so that all elements that satisfy the predicate come before all elements that do not satisfy the predicate. The function returns true if the range is empty.

struct message
{
   std::string text;
   bool delivered;
};

std::vector<message> messages = {
   {"first message", true},
   {"second message", true},
   {"third message", false},
   {"fourth message", false},
   {"fifth message", true},
};

auto is_delivered = [](message const & msg) {return msg.delivered;};

// is not partitioned
std::cout << std::boolalpha
          << std::is_partitioned(std::begin(messages), std::end(messages), is_delivered)
          << std::endl;

// do partition
std::partition(std::begin(messages), std::end(messages), is_delivered);

// is partitioned
std::cout << std::boolalpha
          << std::is_partitioned(std::begin(messages), std::end(messages), is_delivered)
          << std::endl;

is_permutation

Algorithm is_permutation determines whether a range is a permutation of another range. There are two overloads, the first uses operator== to compare the elements of the two ranges and the second takes a binary predicate (that returns true if two elements are equal).

int numbers[] = {1, 2, 42, 7, 0};
int numbers2[] = {0, 1, 2, 7, 42};
std::cout << std::boolalpha
          << std::is_permutation(std::begin(numbers), std::end(numbers), std::begin(numbers2))
          << std::endl;

minmax_element

The minmax_element algorithm finds both the minimum and the maximum element in a range and returns a pair of iterators to these elements. It is important to note that:

  • if the range is empty it returns std::make_pair(first, first)
  • if there is more than one element equal to the minimum value it returns an iterator to the first of these elements
  • if there is more than one element equal to the maximum value it returns an iterator to the last of these elements

There are two overloads, the first uses operator< to compare elements and the second uses a provided comparison function.

std::vector<int> numbers = {1, 2, 7, 42, 0};
std::vector<int>::iterator minimum, maximum;
std::tie(minimum, maximum) = std::minmax_element(std::begin(numbers), std::end(numbers));

std::cout << "minimum = " << *minimum << std::endl;
std::cout << "maximum = " << *maximum << std::endl;

The output is:

minimum = 0
maximum = 42

C++ generic numeric algorithms in header <numeric>

The C++ Standard Library header <numeric> contains several generic numeric algorithms. In this post we take a look at how they can be used for solving real world examples.

Accumulating values

Problem: Given the monthly sales values compute the total sales during a year.

Solution: This is a simple sum that can be computed by iterating over the sales and summing them.

There is an algorithm for that called accumulate. It computes the sum in a given range and the provided initial value. So for our problem this can be put as:

std::vector<double> sales = {1000, 1500, 2000, 1500, 2000, 1000, 
                             3000, 1500, 1200, 1800, 2200, 2000};

auto total_sales = std::accumulate(std::begin(sales), std::end(sales), 0.0);

Problem: Given the monthly inflation rates compute the total inflation during a year.

Solution: If the inflation was 10% in January and 20% in February, the inflation at the end of February is not 30% but 32%. The monthly inflation rates must be multiplied. An overloaded accumulate allows to specify a binary operation to be used for accumulating values, instead of operator+. So the solution to our problem could look like this:

std::vector<double> inflation = {1.01, 1.02, 1.03, 1.04, 1.05, 1.06,
                                 1.06, 1.05, 1.04, 1.03, 1.02, 1.01};

auto total_inflation = std::accumulate(std::begin(inflation), std::end(inflation), 
                                       1.0, 
                                       std::multiplies<double>());

Partial accumulations

Problem: Given the monthly sales values compute the accumulated total sales per whole year at the end of each month. In other words show the sales for January, January to February, January to March, … January to December.

Solution: This is again a simple summing operation where in each loop you have a partial sum. s[0] = v[0], s[1] = v[0] + v[1], s[2] = v[0] + v[1] + v[2], etc.

There is an algorithm called partial_sum that does exactly that: it computes the partial sums of the elements in the given range and writes them in a destination range. There are two overloads of it, one using operator+ and one that allows to specify a binary operation.

std::vector<double> sales = {1000, 1500, 2000, 1500, 2000, 1000, 
                             3000, 1500, 1200, 1800, 2200, 2000};
std::vector<double> acc_sales;

std::partial_sum(std::begin(sales), std::end(sales), std::back_inserter(acc_sales));

The content of acc_sales will be {1000, 2500, 4500, 6000, 8000, 9000, 12000, 13500, 14700, 16500, 18700, 20700}.

Sum of products

Problem: Given the values of daily sales in USD compute the total sales in EUR.

Solution: Computing the total sales in USD and then multiplying with the USD/EUR exchange rate is not a correct solution because the exchange rate varies every day. We must compute the daily sales in EUR and then sum those values. That means we need a sum of products.

Another algorithm in the <numeric> header called inner_product does exactly that. It takes two ranges and an initial value and uses operator* to compute the product and operator+ to sum the products.

std::vector<double> sales_usd = {1000, 2000, 1500, 2000, 2500, 500, 500};

std::vector<double> usd_eur_rates = {0.7260, 0.7249, 0.7263, 0.7287, 0.7287, 0.7287, 0.7297, 
                                     0.7250, 0.7218};

auto sales_eur = std::inner_product(std::begin(sales_usd), std::end(sales_usd),
                                    std::begin(usd_eur_rates),
                                    0.0);

Problem: Given the monthly budgets and the actual sales over an year count how many times the budget was met or exceeded.

Solution: To count how many times the sales where equal or greater than the budget we have to compare the values in each month and increment a value each time the condition was true.

Instead of coding this explicitly we could use an overload of the inner_product algorithm that takes two additional parameters, both binary operations, for the sum operation and the product operation. For the sum we can use std::plus() and for comparison std::greater_equal() (need to include header <functional>).

std::array<double, 12> budget = {1000, 1500, 2000, 1500, 2000, 1000, 
                                 3000, 1500, 1200, 1800, 2200, 2000};

std::array<double, 12> sales  = {1000, 1400, 2100, 2000, 1800,  900, 
                                 3500, 1300, 1000, 2000, 2000, 2500};

auto count = std::inner_product(std::begin(sales), std::end(sales),
                                std::begin(budget),
                                0,
                                std::plus<int>(),
                                std::greater_equal<double>());

The result of the count for the input data is 6.

Adjacent differences

Problem: Given the monthly sales for an year compute the variations (in percentage) between the current and previous monthly sales. If sales in January were 1000 and in February were 1500, then the sales variation for February is 50%.

Solution: We have to iterate through the monthly value and compute (current - prev) / prev for each month. This is an operation applied to adjacent values.

An algorithm called adjacent_difference computes difference between adjacent values in a given ranges and writes them in a destination range. The first element of the input range is copied unmodified to the beginning of the destination range. An overload allows to specify a binary operation to be used instead of operator-.

To solve the proposed problem we call this algorithm on the sales and then remove the first element from the destination range (since it’s just a copy of the sales for the first month). We use a lambda for the binary operation and it simply returns (current - prev) / prev.

std::vector<double> sales = {1000, 1500, 2000, 1500, 2000, 1000, 
                             3000, 1500, 1200, 1800, 2200, 2000};

std::vector<double> vars;
std::adjacent_difference(std::begin(sales), std::end(sales),
                         std::back_inserter(vars),
                         [](double const & v2, double const v1) {return (v2-v1)/v1;});

vars.erase(std::begin(vars));

The result for the given range (shown with 4 decimals) is {0.5000, 0.3333, -0.2500, 0.3333, -0.5000, 2.0000, -0.5000, -0.2000, 0.5000, 0.2222, -0.0909}.

The standard way of converting between numbers and strings in C++11

In C++03 there was no standard way of converting numbers to strings. The best way to do that was using std::stringstream.

int n = 42;
std::stringstream ss;
ss << n;
std::string s = ss.str();

One could put that into a more generic function that looks like this:

template <typename T&gt
std::string to_string(T const & value)
{
    std::stringstream ss;
    ss << value;
    return ss.str();
}

The opposite of converting a text to a number could look like this:

template <typename T>
T my_to_number(std::string const & text)
{
   T value;
   std::stringstream ss(text);
   ss >> value;
   return value;
}

Of course, there was also the option of using C functions such as itoa, sprintf or atoi (or their Microsoft secure version _itoa_s, sprintf_s).

C++11 provides several standard functions for converting numbers to strings and strings to numbers, all of them available in the <string> header.

For converting numbers to strings there are two new overloaded functions: to_string() and to_wstring(). They take one argument of various numeric types (int, long, long long, double, long double, etc.) and return either a std::string or a std::wstring with the number converted to text.

auto as = std::to_string(42);
auto ws = std::to_wstring(3.14);

These functions are actually just wrappers over sprintf and swprintf. According to the standard (section 21.5):

Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of “%d”, “%u”, “%ld”, “%lu”, “%lld”, “%llu”, “%f”, “%f”, or “%Lf”, respectively, where buf designates an internal character buffer of sufficient size.

For the other way around of converting strings to numbers there are several overloaded methods (taking either a std::string or a std::wstring):

  • stoi: converts a string to a signed integer
  • stol: converts a string to a signed long
  • stoll: converts a string to a signed long long
  • stoul: converts a string to an unsigned long
  • stoull: converts a string to an unsigned long long
  • stof: converts a string to a float
  • stod: converts a string to a double
  • stold: converts a string to a long double
std::string as = "42";
std::wstring ws = "3.14"

auto n2 = std::stoi("42");
auto n3 = std::stoul(as);
auto n4 = std::stod(ws);

Functions stof, stod and stold are also just wrappers over strtod and strtold:

the first two functions call strtod(str.c_str(), ptr) and the third function calls strtold(str.c_str(), ptr). Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

atoi() and atol() that convert a null-terminated byte-string (i.e. char*) to an integer or long were already available in header <cstdlib>. There is a new function available in this header called atoll() that converts a null-terminated byte string to a long long value.

auto n = std::atoll("42");

Assigning algorithms in the C++ Standard Library

The C++ Standard Library provides several algorithms for assigning values to a range (such as a container or a C-array).

fill and fill_n

std::fill assigns a given value to all the elements in a range. It is available in the header <algorithm>. In the following example all elements of a vector of integers are assigned the value 1.

std::vector data(10);
std::fill(std::begin(data), std::end(data), 1);

std::fill_n is similar, but instead taking the bounds of a range it takes the beginning and a count and initializes N elements starting from the specified first element. You must make sure that first + count does not exceed the bounds of the range. The following example is an equivalent of the first:

std::vector data(10);
std::fill_n(std::begin(data), data.size(), 1);

generate and generate_n

These algorithms are similar to the first, but instead of taking a value to assign they take a function and assign the value returned by the function. They are also available in the header <algorithm>.

std::generate assigns the elements in a range the values returned by a function.

In the following example we initialize a vector of 10 elements with random numbers (using a Marsenne twister engine).

std::mt19937 rnd(static_cast<unsigned int>(std::chrono::system_clock::now().time_since_epoch().count()));
std::vector<int> data(10);
std::generate(std::begin(data), std::end(data), rnd);

for(auto const & d : data)
{
   std::cout << d << std::endl;
}

The result may look like this:

-630855823
-1828303634
473207879
1464137724
1046536659
1518951902
1516051318
-2076855687
-1620034611
-991968006

You can use lambdas as the function whose return value is stored into the range. The following example generates random numbers ranging from 1 to 100 with a uniform distribution.

std::mt19937 rnd(static_cast(std::chrono::system_clock::now().time_since_epoch().count()));
std::vector data(10);
std::uniform_int_distribution ud(1, 100);
std::generate(std::begin(data), std::end(data), [&](){return ud(rnd);});

for(auto const & d : data)
{
   std::cout << d << std::endl;
}

Result may look like this:

48
10
15
63
34
2
22
71
15
37

std::generate_n is similar, but instead of taking the limits of the range it takes the beginning and a count and assigns the first N values returned by the function to the range. You must makes sure that first + count does not exceeds the bounds of the range.

In the following example we initialize the elements of a vector with values from 1 to N, where N is the size of the range.

std::vector data(10);
int n = 1;
std::generate_n(std::begin(data), data.size(), [&](){return n++;});

for(auto const & d : data)
{
   std::cout << d << std::endl;
}

The result is:

1
2
3
4
5
6
7
8
9
10

iota

std::iota is a new algorithm to C++11. It assigns the elements of a range with sequentially increasing values starting from a given value. The algorithm is available in header <numeric>.

The following example initializes the elements of a vector with values from 1 to N, where N is the size of the range (basically the same thing we did in the last example).

std::vector data(10);
std::iota(std::begin(data), std::end(data), 1);

for(auto const & d : data)
{
   std::cout << d << std::endl;
}

The result is:

1
2
3
4
5
6
7
8
9
10

Notice that the term iota is taken from the APL programming language and denotes the Greek letter used in various mathematical notations.

Function return type deduction in C++14

C++11 introduced the auto keyword as a placeholder for types. It could be used for declaring variables but also for the return type of a function, given than you use a new syntax with a trailing type at the end of the function.

auto foo() -> int 
{
   return 42;
}

or

template 
auto foo(T value) -> decltype(value.bar())
{
   return value.bar();
}

This is a bit cumbersome and too explicit so C++14 takes the next step and makes the trailing return type unnecessary. Under C++14 the above examples can be simply written as:

auto foo()
{
   return 42;
}

and

template 
auto foo(T value)
{
   return value.bar();
}

There are several things to keep in mind:

  • if a function has more than one return statement they all must deduce the same type
    auto foo()
    {
      if(condition) 
         return 1;
    
      return 0;
    }
    
  • a recursive function can have an auto return type only if it has a non-recursive return statement before the recursive call.
    auto fibonacci(int n)
    {
       if(n<=2) return 1;
       else return fibonacci(n-1) + fibonacci(n-2);
    }
    
  • a function with an auto return type can be forward declared, but cannot be used until it has been defined

In my personal opinion auto return type should be used with caution. It can make the code harder to read and maintain (you don’t know the type just by looking at the signature), harder to document (automatic documenting tools use the signature to produce documentation), and can lead to situations when the developer expects one return type but the compiler generates another.

Additional readings:

Inherited constructors in C++11

In C++, a function in a derived class with the same name as one (or a set of overloads) in a base class, hides the function (or the overloads) from the base class. Here is an example:

struct base 
{
   void foo() {std::cout << "base::foo" << endl;}
   void foo(int a) {std::cout << "base::foo(" << a << ")" << endl;}
   void foo(int a, double b) {std::cout << "base::foo(" << a << "," << b << ")" << endl;}
};

struct derived : base
{
   void foo(double a) {std::cout << "derived::foo(" << a << ")" << endl;}
};

int main()
{
   derived d;

   d.foo();          // error: derived::foo does not take 0 arguments
   d.foo(42);
   d.foo(42, 3.14);  // error: derived::foo does not take 2 arguments

   return 0;
}

As the comments show, calls to foo() and foo(42, 3.14) trigger compiler errors. The call to foo(42) is all right because there is an implicit conversion from int to double.

It is possible to “un-hide” the functions from the base class with a using directive.

struct derived : base
{
   void foo(double a) {std::cout << "derived::foo(" << a << ")" << endl;}
   using base::foo;
};

The code in main will now compile and the program will output:

base::foo
base::foo(42)
base::foo(42,3.14)

A limitation of this feature was that it didn’t work with constructors. In other words the following is failing to compile.

struct base 
{
   base() {std::cout << "base()" << endl;}
   base(int a) {std::cout << "base(" << a << ")" << endl;}
   base(int a, double b) {std::cout << "base(" << a << "," << b << ")" << endl;}
};

struct derived : base
{
   using base::base;
};

int main()
{
   derived d1;
   derived d2(42);
   derived d3(42, 3.14);

   return 0;
}

This can be achieved by writing a matching constructor in the derived for every constructor in base.

struct derived : base
{
   derived():base() {}
   derived(int a):base(a) {}
   derived(int a, double b):base(a, b) {}
};

However, when you have hierarchies with many derives and you have to provide one or more constructors like this just to call the right constructor of base it becomes annoying.

A solution to the problem is provided by C++ 11. The using directive now works also for constructors. The derived class in the last example is semantically equivalent to

struct derived : base
{
   using base::base;
};

This code will produce the following output:

int main()
{
   derived d1;
   derived d2(42);
   derived d3(42, 3.14);

   return 0;
}
base()
base(42)
base(42,3.14)

Keep in mind that the lifted constructors are simply calling the base constructors and do not perform any member initialization. Suppose you had some member like in the following example:

struct derived : base
{
   using base::base;

   int value;
};

Regardless what constructor is used to create the object, value will remain uninitialized. To avoid that you have two options:

  • don’t use the using directive to lift the constructors from base and write the constructors for the derived class explicitly
  • initialize the member variables explicitly (using non-static data member initializers):
    struct derived : base
    {
       using base::base;
    
       int value {0};
    };
    

Availability. At the time of writing this post, inherited constructors are supported by g++ 4.8 and clang 3.3. Visual Studio does not support it and is not known in which version in the future it will. Non-static data member initializers are supported by Visual Studio 2013 RTM, g++ 4.7 and clang 3.0.

Farewell to new and delete

C++11 introduced several smart pointers (residing in the <memory> header):

  • std::shared_ptr: retains shared ownership of an object, that is destroyed when the last shared_ptr that holds a reference to it is destroyed or assigned another pointer.
  • std::unique_ptr: retains sole ownership of an object, that is destroyed when the unique_ptr goes out of scope
  • std::weak_ptr: retains a non-owning reference to an object managed by a shared_ptr. It does not participate in the reference counter of the shared pointer. It is mainly use to break circular dependencies.
std::shared_ptr<int> p1(new int(42));
std::shared_ptr<int> p2(p1);
std::weak_ptr<int> w1 = p1;
std::unique_ptr<int> u1(new int(42));

While these smart pointers manage resources automatically, so there is no need to delete object explicitly, they still require explicit instantiation with new for the managed resource.

C++11 introduced std::make_shared, a free function that constructs an object and wraps it in a std::shared_ptr object.

auto p1 = std::make_shared<int>(42);

C++14 introduces another free function, std::make_unique, that constructs an object and wraps it in a std::unique_ptr object.

auto u1 = std::make_unique<int>(42);

With these smart pointer and functions available there is no need any more to use new and delete in your C++ code. Besides avoiding explicit allocation and release these functions have another important advantage: they prevent memory leaks that could happen in the context of function calls. You can read Herb Sutter’s GotW #102: Exception-Safe Function Calls for details about this problem.