Articles & Books

Bjarne Stroustrup awarded 2017 Faraday Medal

The Faraday Medal is awarded for conspicuous service rendered to the advancement of science, engineering and technology:

Bjarne Stroustrup awarded 2017 Faraday Medal

by Institution of Engineering and Technology

From the article:

“I am honored and humbled to see my name among so many illustrious previous winners of the prize,” said Stroustrup. “This privilege is only possible through the superb work of the C++ community.”

Static libs do not modular make -- Thomas Young

An article about static libraries, the benefits (or non-benefits) of splitting your project into static libraries, and the knock-on effects this can have on project dependencies.

Static libs do not modular make

by Thomas Young

From the article:

A cautionary tale about statically-linked libraries, as generated by C/C++ build tools.

As a project accumulates features, and complexity, it gets harder to understand exactly what's going on, and to find your way around the source code. You need to find some way to organise the code and try and keep things manageable.

A common idea, in this situation, is to group some source files together to split out as a static library.

I'm going to argue that this actually does very little, in itself, to increase modularity, can have the effect of significantly increasing dependencies, and is maybe not such a good idea, after all.

Quick Q: What are template deduction guides in C++17?

Quick A: A solution for automatic template resolution on constructors.

Recently on SO:

What are template deduction guides in C++17?

Template deduction guides are patterns associated with a template class that tell the compiler how to translate a set of parameter (and their types) into template arguments.

The simplest example is that of std::vector and its constructor that takes an iterator pair.

template<typename Iterator>
void func(Iterator first, Iterator last)
{
  vector v(first, last);
}

The compiler needs to figure out what vector<T>'s T type will be. We know what the answer is; T should be typename std::iterator_traits<Iterator>::value_type. But how do we tell the compiler without having to type vector<typename std::iterator_traits<Iterator>::value_type>?

You use a deduction guide:

template<typename Iterator> vector(Iterator b, Iterator e) -> vector<typename std::iterator_traits<Iterator>::value_type>;

This tells the compiler that, when you call a vector constructor matching that pattern, it will deduce the vector specialization using the code on the right of ->.

You need guides when the deduction of the type from the arguments is not based on the type of one of those arguments. Initializing a vector from an initializer_list explicitly uses the vector's T, so it doesn't need a guide.

The left side doesn't necessarily specify a constructor. The way it works is that, if you use template constructor deduction on a type, it matches the arguments you pass against all deduction guides (actual constructors provide implicit guides). If there is a match, it uses that to determine which template arguments to provide to the type. But overload resolution to determine which constructor to call happens after that.

This also means that you can use guides with aggregates and aggregate initialization:

template<typename T>
struct Thingy
{
  T t;
};

Thingy(const char *) -> Thingy<std::string>;

Thingy thing{"A String"}; //thing.t is a `std::string`.

So deduction guides are only used to figure out the type being initialized. The actual process of initialization works exactly as it did before, once that determination has been made.

Detection Idiom - A Stopgap for Concepts--Simon Brand

Concepts are not yet here, but there are solutions.

Detection Idiom - A Stopgap for Concepts

by Simon Brand

From the article:

Concepts is a proposed C++ feature which allows succinct, expressive, and powerful constraining of templates. They have been threatening to get in to C++ for a long time now, with the first proposal being rejected for C++11. They were finally merged in to C++20 a few months ago, which means we need to hold on for another few years before they’re in the official standard rather than a Technical Specification. In the mean time, there have been various attempts to implement parts of concepts as a library so that we can have access to some of the power of Concepts without waiting for the new standard. The detection idiom – designed by Walter Brown and part of the Library Fundamentals 2 Technical Specification – is one such solution. This post will outline the utility of it, and show the techniques which underlie its implementation.

Automatic two-phase init -- Krzysztof Ostrowski

Deferred initialisation for classes that inherit constructors, or Automatic two-phase init.

Deferred initialisation for classes that inherit constructors

by Krzysztof Ostrowski

From the article:

Constructor inheritance through using-declaration is a powerful technique that can be easily used to introduce pre-defined behaviour to custom types. As an example, consider a generic visitor design pattern implementation that is parametrised by the names of visitable types, and an unique tag that identifies given visitor template instance. Such an instance can be "mixed-in" into a custom type D by simply deriving from it... and inheriting its constructors to make it behave as it would be a Visitor template instance itself:

struct D
  : Visitor<
        A         // the tag
      , X, Y, Z   // "list" of visitable types
      >
{
    using Visitor::Visitor;
};
What if there is a need to run an "additional" initialisation code as it would be run in the D constructor if one were there? Bjarne Stroustrup suggests member-initializers that do half of a work we would like to do here. While direct member initialisation sets required initial values for all the members (except bit field members), it does not offer a direct way to execute custom code that makes use of those members, the custom code that typically resides in the constructor's body.
This article presents a solution that enables injection of a custom code to be executed once all the non-static members are initialised.

The main() Course -- Adi Shavit

A fanciful little post about li’l old main().

The main() Course

by Adi Shavit

From the article:

The function main() is a normal program’s entry point.

The shortest conforming C++ executable program is: int main(){}

Quick Q: Array Initialisation Compile Time - Constexpr Sequence

Quick A: Use integer_sequence with a helper function.

Recently on SO:

Array Initialisation Compile Time - Constexpr Sequence

1) How to implement that kind of integer_sequence?

template <std::size_t... Is>
constexpr auto make_sequence_impl(std::index_sequence<Is...>)
{
    return std::index_sequence<generate_ith_number(Is)...>{};
}

template <std::size_t N>
constexpr auto make_sequence()
{
    return make_sequence_impl(std::make_index_sequence<N>{});
}

2) Is it possible to build an std::array from that integer_sequence at compile time?

template <std::size_t... Is>
constexpr auto make_array_from_sequence_impl(std::index_sequence<Is...>)
{
    return std::array<std::size_t, sizeof...(Is)>{Is...};
}

template <typename Seq>
constexpr auto make_array_from_sequence(Seq)
{
    return make_array_from_sequence_impl(Seq{});
}

Usage:

int main()
{
    constexpr auto arr = make_array_from_sequence(make_sequence<6>());
    static_assert(arr[0] == 0);
    static_assert(arr[1] == 1);
    static_assert(arr[2] == 2);
    static_assert(arr[3] == 4);
    static_assert(arr[4] == 5);
    static_assert(arr[5] == 7);
}

Quick Q: vector of vector does not convert brace encloser list

Quick A: The constructor needs an extra {} pair.

Recently on SO:

vector does not convert brace encloser list

You have two options:

  1. add a constructor taking std::initializer_list<std::initializer_list<T>>
  2. eclose the init expression with another set of {} i.e.
Matrix<double> a{{

    { 17,    24,    1},

    { 23,    5,     7 },

    {  4,     6,    13 }

}};

Ok, I'll try a little explanation of what is going on here:

If there is no constructor taking a std::initializer_list then the outermost {} are always opening and closing the constructor call if you will, and not part of what you actually pass to the constructor.

Matrix<double> a{ {1, 2}, {3, 4} };
                ^ ^~~~~~~~~~~~~~ ^
                |  2 parameters  |
                |                |
                |                |
            opening            closing

As you can see this is taken as a constructor with 2 parameters, in this case 2 initializer_lists.

This is why you need another set of {}:

Matrix<double> a{ {{1, 2}, {3, 4}} };
                ^ ^~~~~~~~~~~~~~~~ ^
                |  1 parameter     |
                |                  |
                |                  |
            opening            closing

In order for the outermost {} to be considered an initializer_list then the constructor needs to have an overload taking a initializer_list. That is what is happening in the std::vector case.