Structured iteration

It is relatively easy to get your for-loops wrong. Luckily, C++ offers more and more bug-proof alternatives.

The post is available at the new blog location: https://thecppway.com/posts/structured_iteration/.

Posted in programming | Tagged , , , | Leave a comment

A new blog location

I have decided to move Andrzej’s C++ blog to a new location.
It is now at https://thecppway.com and has been rebranded to The C++ way.
You will now get a more modest experience, but without disturbing advertisements and with the ability to comment using the markdown syntax.

Posted in Uncategorized | 2 Comments

Event-driven flows

This post is in response to two claims about coroutines:

  1. Their reference function parameters may become dangling too easily.
  2. They are indistinguishable from regular functions from the declaration alone.

But rather than talking about coroutines, we will look at event-driven control flows in general. Modelling them is one of the primary motivations (alongside “generators”) for having coroutines. By understanding the need we will be better equipped to understand the tool. Continue reading

Posted in programming | Tagged , , , , | 2 Comments

Concepts vs type traits

What is the difference between a concept and a type trait? Note that you can create a type trait using a requires-expression:

template <typename T>
constexpr bool has_fun = requires(T v) {
  v.fun();
};

You can also constrain a template with a type trait using a requires-clause:

template <typename T>
  requires std::is_standard_layout_v<T>
void fun(T v);

There are differences though. Some are in the language, some in the tools, and one is human communication.

Continue reading

Posted in programming | Tagged , , | 1 Comment

Class invariants

The primary motivation for defining a class in C++ is to reflect and maintain a class invariant. In this post we will see what class invariants are and how you deal with them. Class invariants are important part of C++, even though there is no “invariant” keyword in C++. Continue reading

Posted in programming | Tagged , , , | 1 Comment

The double life of objects

Some common knowledge: the lifetime of the object starts when its initialization is complete. Based on this we can get some further expectations: an object becomes const only after its initialization is complete. But this lifetime property of objects becomes blurred when copy elision comes into play. When a copy is elided, we have a situation where we would otherwise have two objects, each initialized separately, but now they are blended into one, its life time spanning across the caller and the calle, which has a number of surprising effects, receiving two initializations being one of them. Continue reading

Posted in programming | Tagged , | 2 Comments

The obvious final step

The title may be misleading, as I had to invent a new short term for the pattern that occurs in the code once in a while. Example first:

// write an element of an XML file

xml.begin_element("port");
xml.attribute("name", name);
xml.attribute("location", loc);
xml.end_element("port");  // <-- the obvious final step

During the construction of an XML file when you write an element, it is obvious that the last thing that you do is to write the closing tag. By obvious we mean:

  • Writing it down adds no new information (there is no other possible final instruction for this task).
  • It would be a bug if this instruction wasn’t there.

For this reason, people invent tools that allow expressing this type of business logic in a way that does not require of the programmer to write down the obvious final step. An oft used technique is to employ destructors. However, this is very difficult to get right and not implementable in general. In this post we will see why, and we will also see an alternative.

Continue reading

Posted in programming | Tagged , , , | 14 Comments

A moved-from optional

This post is in response to claims, that I have heard number of times, that the semantics of optional’s move operations are wrong:

template <typename T>
void test(T v)
{
  optional<T> o = v;
  assert (o);     // o contains a value
  optional<T> p = std::move(o);
  assert (o);     // o still contains a value!
}

Some people are surprised that the second assert holds: the unfulfilled expectation is that moving from an optional should “eject” the value and leave the object in the state of not containing any value. While such semantics could be made to work, there are good reasons for preferring the present behavior. Continue reading

Posted in programming | Tagged , , , | 2 Comments

Local Time

In this post we will see how to solve the task from the previous post, but display the time point in local time instead of system time. The solution is simple and takes only two additional lines (you can scroll down towards the end), but I want to take this opportunity to offer some reflections about the concepts of time zones and daylight saving time. Continue reading

Posted in programming | Tagged , | 6 Comments