intermediate

How to Pass a Polymorphic Object to an STL Algorithm--Jonathan Boccara

Did you ever try?

How to Pass a Polymorphic Object to an STL Algorithm

by Jonathan Boccara

From the article:

As we can read in the opening chapter of Effective C++, C++ is a federation of 4 languages:

  • the procedural part coming from C,
  • the object-oriented part,
  • the STL part (following a functional programming paradigm),
  • the generic part with templates.

And what’s more, all of those 4 sub-languages are part of one whole: the C++ language. Those 4 paradigms begin united in one language gives opportunities for them to interact – and often, those interactions create interesting situations.

Today we’re focusing on one particular interaction, between the object-oriented model and the STL. There could be multiple forms for this interaction, and the case we will look at is how to pass a polymorphic (that is, having virtual methods) function object to an STL algorithm.

Which One Is Better: Map of Vectors, or Multimap?--Jonathan Boccara

Depends!

Which One Is Better: Map of Vectors, or Multimap?

by Jonathan Boccara

From the article:

While advising on how to make code more expressive on the SFME project, I came across an interesting case of choosing the right data structure, which I’ll share with you with the permission of the authors of the projects.

We had to associate a key with several values, and perform various operations. Should we use a map of vectors, or is a multimap more appropriate? Let’s see the case in more details, and compare the two solutions...

Getting the Benefits of Strong Typing in C++ at a Fraction of the Cost--Vincent Zalzal

Very interesting!

Getting the Benefits of Strong Typing in C++ at a Fraction of the Cost

by Vincent Zalzal

From the article:

Strong types promote safer and more expressive code. I won’t repeat what Jonathan has presented already in his series on strong types.

I suspect some people may find that the NamedType class template has a nice interface but is using a somewhat heavy machinery to achieve the modest goal of strong typing. For those people, I have good news: you can achieve many of the functionalities of NamedType, with a very simple tool. That tool is the humble struct...

Quick Q: Why does unary operator & not require a complete type?

Quick A: It only need to take the address.

Recently on SO:

Why does unary operator & not require a complete type?

What if stru has overloaded operator&()?

Then it is unspecified whether the overload will be called (See Oliv's comment for standard quote).

How could unary operator & does not require a complete type?

That's how the standard has defined the language. The built-in address-of operator doesn't need to know the definition of the type, since that has no effect on where to get the address of the object.

One consideration for why it is a good thing: Compatibility with C.

Quick Q: Why does shared_ptr needs to hold reference counting for weak_ptr?

Quick A: To know when to deallocate the control block.

Recently on SO:

Why does shared_ptr needs to hold reference counting for weak_ptr?

The reference count controls the lifetime of the pointed-to-object. The weak count does not, but does control (or participate in control of) the lifetime of the control block.

If the reference count goes to 0, the object is destroyed, but not necessarily deallocated. When the weak count goes to 0 (or when the reference count goes to 0, if there are no weak_ptrs when that happens), the control block is destroyed and deallocated, and the storage for the object is deallocated if it wasn't already.

The separation between destroying and deallocating the pointed-to-object is an implementation detail you don't need to care about, but it is caused by using make_shared.

If you do

shared_ptr<int> myPtr(new int{10});

you allocate the storage for the int, then pass that into the shared_ptr constructor, which allocates storage for the control block separately. In this case, the storage for the int can be deallocated as early as possible: as soon as the reference count hits 0, even if there is still a weak count.

If you do

auto myPtr = make_shared<int>(10);

then make_shared might perform an optimisation where it allocates the storage for the int and the control block in one go. This means that the storage for the int can't be deallocated until the storage for the control block can also be deallocated. The lifetime of the int ends when the reference count hits 0, but the storage for it is not deallocated until the weak count hits 0.

Is that clear now?