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 , , | 12 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

Declaring the move constructor

Update. I have updated the post a bit, as it misled a number of people to think that you need to define the move constructor in a cpp file. This is not so. I have now also highlighted another important feature of my solution: statically checked noexcept specification.

I am not satisfied with the solution I gave in the previous post. The proposed interface was this:

class Tool
{
private:
  ResourceA resA_;
  ResourceB resB_;
  // more resources
 
public:
  // Tools's interface
 
  Tool(Tool &&) = default;           // noexcept is deduced
  Tool& operator=(Tool&&) = default; // noexcept is deduced
 
  Tool(Tool const&) = delete;
  Tool& operator=(Tool const&) = delete;
};

static_assert(std::is_move_constructible<Tool>::value, "...");
static_assert(std::is_move_assignable<Tool>::value, "...");

In a way, it is self contradictory. The whole idea behind departing from the Rule of Zero is to separate the interface from the current implementation. Yet, as the comments indicate, the exception specification is deduced from the current implementation, and thus unstable. Continue reading

Posted in programming | Tagged , , , | 11 Comments

Special member functions

Update. One remark in this post about compile-time messages was untrue. As K-ballo has pointed out, declaration =default does not mean that we have a declared and usable member function. Ville Voutilainen also suggested how to fix the situation with a static_assert. This section is now corrected.

Update. I no longer consider the advice given in this post a good one. I left it for reference, but I encourage you to also read this post.

You have probably already heard about the Rule of Zero formulated by R. Martinho Fernandes:

Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership. Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators.

I have run into a certain problem when trying to apply it, and today I wanted to share my observations with you. I noted that Scott Meyers also expressed his concerns about some interpretations of the rule (see here); I came to a similar conclusion, however my problem is somewhat different. Continue reading

Posted in programming | Tagged | 9 Comments

Can you see the bug?

Recently, I was hit by one C++11 gotcha. It is funny: I know about it, I have blogged about it, and nonetheless I still fell into the trap. Continue reading

Posted in programming | Tagged , | 9 Comments

code::dive — call for papers

Today an announcement about the code::dive conference for software developers hosted in Wrocław, Poland in November. The call for papers is still open. It may be your chance to share your experience with other programmers. I attended the conference last year and found it quite interesting.

Posted in programming | Leave a comment