basics

Using C++17 std::optional—Bartlomiej Filipek

A reminder.

Using C++17 std::optional

by Bartlomiej Filipek

From the article:

Let’s take a pair of two types <YourType, bool> - what can you do with such composition?

In this article, I’ll describe std:optional - a new helper type added in C++17. It’s a wrapper for your type and a flag that indicates if the value is initialized or not. Let’s see where it can be useful and how you can use it.

Passing Booleans to an Interface in an Expressive Way—Jonathan Boccara

Readability is important.

Passing Booleans to an Interface in an Expressive Way

by Jonathan Boccara

From the article:

In order to allow a function to behave in several different way, and to allow its caller to choose amongst these behaviours, we have several tools at our disposal. Plenty, actually.

There are various sorts of polymorphisms embedded in the language such as virtual functions and templates. And we’ve also seen that a caller can specify the desired behaviour explicitly at call site. We’ve seen how to accomplish this by using tag dispatching, and also how to choose between enums and tag dispatching depending on your need.

I now want to top it off with a really simple technique, that will cost you almost nothing, but one that will make your code much more expressive. And even if it’s not rocket science I’m sharing this with you today because I’ve seen many a piece of code that could have benefited from it...

Quick Q: What is a non-trivial constructor in C++?

Quick A: All constructors that you define are not trivial.

Recently on SO:

What is a non-trivial constructor in C++?

In simple words a "trivial" special member function literally means a member function that does its job in a very straightforward manner. The "straightforward manner" means different thing for different kinds of special member functions.

For a default constructor and destructor being "trivial" means literally "do nothing at all". For copy-constructor and copy-assignment operator, being "trivial" means literally "be equivalent to simple raw memory copying" (like copy with memcpy).

If you define a constructor yourself, it is considered non-trivial, even if it doesn't do anything, so a trivial constructor must be implicitly defined by the compiler.

In order for a special member function to satisfy the above requirements, the class must have a very simplistic structure, it must not require any hidden initializations when an object is being created or destroyed, or any hidden additional internal manipulations when it is being copied.

For example, if class has virtual functions, it will require some extra hidden initializations when objects of this class are being created (initialize virtual method table and such), so the constructor for this class will not qualify as trivial.

For another example, if a class has virtual base classes, then each object of this class might contain hidden pointers that point to other parts of the very same object. Such a self-referential object cannot be copied by a simple raw memory copy routine (like memcpy). Extra manipulations will be necessary to properly re-initialize the hidden pointers in the copy. For this reason the copy constructor and copy-assignment operator for this class will not qualify as trivial.

For obvious reasons, this requirement is recursive: all subobjects of the class (bases and non-static members) must also have trivial constructors.

C++17: Initializers for if & switch statements—Marc Gregoire

Small reminder:

C++17: Initializers for if & switch statements

by Marc Gregoire

From the article:

Two small, but very useful C++17 features are initializers for if and switch statements. These can be used to prevent polluting the enclosing scope with variables that should only be scoped to the if and switch statement. The for statement already supports such initializers since the beginning...

Quick Q: Is (4 > y > 1) a valid statement in C++? How do you evaluate it if so?

Quick A: This is not a valid statement.

Recently on SO:

Is (4 > y > 1) a valid statement in C++? How do you evaluate it if so?

The statement (4 > y > 1) is parsed as this:

((4 > y) > 1)

The comparison operators < and > evaluate left-to-right.

The 4 > y returns either 0 or 1 depending on if it's true or not.

Then the result is compared to 1.

In this case, since 0 or 1 is never more than 1, the whole statement will always return false.