Bitfields and strongly-typed enums

Something is wrong with the following code, can you spot what it is? (If in doubt, try compiling it.)

enum class Color { red = 1, green = 2, blue =  4 };
auto yellow = Color::red | Color::green;

As you may have found out, the compiler complains with a message such as: error: no match for 'operator|' (operand types are 'Color' and 'Color'). The simplistic solution is to remove the class keyword, and use the “plain” enum type, where the enumerators are implicitly convertible to and from int.

Continue reading “Bitfields and strongly-typed enums”

String literals as switch/case labels

This article aims to show that switching on string values and matching them with string-valued case labels is both practical and possible in Modern C++ (since C++17), with a minimal amount of boilerplate code being necessary. The C++ switch statement is almost unchanged since the days of C, apart from the availability of the [[fallthrough]]; attribute to allow a non-empty case to fall through to the next, and the possibility of preceding the switch expression with an initializer. Importantly, case labels can still be only of integral type (from char up to long long).

The steps needed are as follows:

  1. Create a hashing function that generates an integral hash from a string (we’ll use C++17’s std::string_view as the source type)
  2. Make sure this function can be declared constexpr (again, this needs C++17)
  3. Write an operator"" function (again constexpr) which calls the hashing function
Continue reading “String literals as switch/case labels”