intermediate

Quick Q: What is the usefulness of `enable_shared_from_this`?

Quick A: It allows you to get a valid shared pointer from your instance directly.

Recently on SO:

What is the usefulness of `enable_shared_from_this`?

It enables you to get a valid shared_ptr instance to this, when all you have is this. Without it, you would have no way of getting a shared_ptr to this, unless you already had one as a member. This example from the boost documentation for enable_shared_from_this:

class Y: public enable_shared_from_this<Y>
{
public:

    shared_ptr<Y> f()
    {
        return shared_from_this();
    }
}

int main()
{
    shared_ptr<Y> p(new Y);
    shared_ptr<Y> q = p->f();
    assert(p == q);
    assert(!(p < q || q < p)); // p and q must share ownership
}

The method f() returns a valid shared_ptr, even though it had no member instance. Note that you cannot simply do this:

class Y: public enable_shared_from_this<Y>
{
public:

    shared_ptr<Y> f()
    {
        return shared_ptr<Y>(this);
    }
}

The shared pointer that this returned will have a different reference count from the "proper" one, and one of them will end up losing and holding a dangling reference when the object is deleted.

enable_shared_from_this is going to be a part of the new C++0x standard as well, so you can also get it from there as well as from boost.

Abstraction design and implementation: `repeat` -- Vittorio Romeo

This series of two articles covers the train of thought behind the design and implementation of a simple `repeat` abstraction that, given a number `n` and a function object `f`, invokes `f` `n` times. The abstraction can be used to repeat actions both at run-time and compile-time. The articles also cover importance of propagating `noexcept`-correctness (and the pain caused by it!).

abstraction design and implementation: `repeat`

compile-time `repeat` & `noexcept`-correctness

by Vittorio Romeo

From the articles:

In my previous "passing functions to functions" and "zero-overhead C++17 currying & partial application" articles I've praised C++11 (and newer standards) for allowing us to write "more functional" code. [...] If I want to repeat an action n times, I exactly want to write that in my code:

    repeat(10, []
    {
        foo();
    });

Cannot get simpler than that - let's implement it!

Quick Q: can i use move only exception throwable objects with vectors?

Quick A: Yes, but with unspecified behavior in case of exception thrown.

Recently on SO:

Using an object without copy and without a noexcept move constructor in a vector. What actually breaks and how can I confirm it?

A vector reallocation attempts to offer an exception guarantee, i.e. an attempt to preserve the original state if an exception is thrown during the reallocation operation. There are three scenarios:

  1. The element type is nothrow_move_constructible: Reallocation can move elements which won't cause an exception. This is the efficient case.
  2. The element type is CopyInsertable: if the type fails to be nothrow_move_constructible, this is sufficient to provide the strong guarantee, though copies are made during reallocation. This was the old C++03 default behaviour and is the less efficient fall-back.
  3. The element type is neither CopyInsertable nor nothrow_move_constructible. As long as it is still move-constructible, like in your example, vector reallocation is possible, but does not provide any exception guarantees (e.g. you might lose elements if a move construction throws).

The normative wording that says this is spread out across the various reallocating functions. For example, [vector.modifiers]/push_back says:

If an exception is thrown while inserting a single element at the end and T is CopyInsertable or is_nothrow_move_constructible_v<T> is true, there are no effects. Otherwise, if an exception is thrown by the move constructor of a non-CopyInsertable T, the effects are unspecified.

I don't know what the authors of the posts you cite had in mind, though I can imagine that they are implicitly assuming that you want the strong exception guarantee, and so they'd like to steer you into cases (1) or (2).

Mutable--Arne Mertz

Do you know that keyword?

Mutable

by Arne Mertz

From the article:

The mutable keyword seems to be one of the less known corners of C++. Yet it can be very useful, or even unavoidable if you want to write const-correct code or lambdas that change their state...

Quick Q: Why would one use nested classes in C++?

Quick A: To hide implementation details

Recently on SO:

Why would one use nested classes in C++?

Nested classes are cool for hiding implementation details

List:

class List
{
    public:
        List(): head(NULL), tail(NULL) {}
    private:
        class Node
        {
              public:
                  int   data;
                  Node* next;
                  Node* prev;
        };
    private:
        Node*     head;
        Node*     tail;
};

Here I don't want to expose Node as other people may decide to use the class and that would hinder me from updating my class as anything exposed is part of the public API and must be maintained forever. By making the class private, I not only hide the implementation I am also saying this is mine and I may change it at any time so you can not use it.

Look at std::list or std::map they all contain hidden classes (or do they?). The point is they may or may not, but because the implementation is private and hidden the builders of the STL were able to update the code without affecting how you used the code, or leaving a lot of old baggage laying around the STL because they need to maintain backwards compatibility with some fool who decided they wanted to use the Node class that was hidden inside <list>.

Keynotes at Meeting C++ 2017

With the conference just a few weeks away, an update on the 3 awesome keynotes of this years Meeting C++:

Keynotes at Meeting C++ 2017

by Jens Weller

From the article:

Are you excited for Meeting C++ 2017?!? I quickly wanted to give an update on the 3 keynotes at the conference this year! Each day will feature one keynote, where the first two are in the morning, while the Closing Keynote is kind of the last thing to happen before the closing message. Also, all 3 keynote speakers have now (finally) their speaker profile.

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.