Diagnosable validity

Certain combinations of types and expressions can make a C++ program ill-formed. “Ill-formed” is a term taken from the C++ Standard and it means that a program is not valid, and compiler must (in most of the cases) reject it. This is quite obvious:

int main()
{
  auto i = "some text".size(); // invalid expression
};

String literals do not have member functions, therefore compiler cannot accept this program, and must report an error. This puts a responsibility on programmers to learn which expressions and types are valid in a given context and use only these. Again, I am saying a very obvious thing.

What is less obvious is that there is a way in C++ to enter a type or expression of which we do not know if it is valid or not, in an isolated environment, where it does not render the entire program ill-formed, but instead it returns a yes-no (or rather valid-invalid) answer, which we can use at compile-time to make a decision how we want the program to behave. When requested, compiler can analyze all the declarations it has seen so far, and make an approximated judgement whether a given type or expression would make the program ill-formed or not, if used outside the isolated environment. The compiler’s approximated answer is not always correct, but it is just enough most of the time. Continue reading

Posted in programming | Tagged , , , , | 5 Comments

Sessions and object lifetimes

In this post we will see how C++ object lifetime can be used to control the duration of sessions: time spent owing and using a resource. The goal is to get a better understanding of what tools the language offers for using and sharing resources efficiently. Continue reading

Posted in programming | Tagged , , , | 6 Comments

Concepts without Concepts

“Concept” can mean two things in the context of C++ generic libraries:

  1. Something informal: something we know about template parameters, and can tell to other human programmers, e.g. in documentation.
  2. A language feature.

This post is about concepts in the first sense. It claims that we had concepts for quite a while already, and shows how we can use them to make generic libraries easier to use. Continue reading

Posted in programming | Tagged , , , , | 10 Comments

Another polymorphism

In this post we will try to see by a practical example what Boost.Variant is for. You can sometimes see examples that use type variant<int, double, string>, but to me they are artificial: I never needed to use something that is either a double or int; but I still consider this library useful. Even if you are already familiar with Boost.Variant an its concepts of “never-empty guarantee” and “static visitor”, I made sure there is still something you can get from reading this post. Continue reading

Posted in programming | Tagged , , , , , | 18 Comments

A customizable framework

In this post I want to describe a problem my colleagues have faced a couple of times recently, and show how it can be solved with C++. Here is the goal. We want to provide a function (or a set of overloaded functions) that would ‘do the right job’ for ‘practically any type’, or for ‘as many types as possible’. As an example of such ‘job’ consider std::hash: what we want to avoid is the situation, where you want to use some type X as a key in the standard hash-map, but you are refused because std::hash does not ‘work’ for X. In order to minimize the disappointment, the Standard Library makes sure std::hash works with any reasonable built-in or standard-library type. For all the other types, that the Standard Library cannot know in advance, it offers a way to ‘customize’ std::hash so that they can be made to work with hash-maps.

For another popular example, consider Boost.Serialization library. Its goal is that almost any type should be serializable with the same interface: the library knows how to serialize, built-in, std and boost popular types, and it offers a way to teach it to serialize new types.

We are going to see a number of ways how such a customizable framework can be implemented. Continue reading

Posted in programming | Tagged , , | 20 Comments

Overload resolution

This post is an introduction to another one that I intend to write in the future. The goal of this one is to go over the concepts of function template specialization, function (template) overloading, argument dependent lookup (ADL) and overload resolution. By no means do I intend to make it a complete reference. My only goal is to briefly show what these things are, what they can do, and what they cannot do, so that you can use them to solve practical problems. I tried to make this post as easy to understand as possible and to avoid the technical nomenclature where possible. Continue reading

Posted in programming | Tagged , , , , | 14 Comments

More than you need

The classes you design can do more (in terms of allowed operations) than what you could figure out from just looking at their member function declarations. The C++ Standard defines a number of cases where certain expressions involving your type are valid, even though there are no corresponding member function declarations. Sometimes this is just what you need; but sometimes the additional operations you never asked for can have grave negative impact on your program correctness. Continue reading

Posted in programming | Tagged , , , , , | 14 Comments