De laatste jaren begint mijn relatie met C++ behoorlijke haat-liefdetrekjes te vertonen. Aan de ene kant is het een enorm krachtige taal waarin je veel problemen prachtig elegant kunt oplossen. Aan de andere kant haal je jezelf nogal wat op de hals als je een groot project in C++ gaat maken: bouwtijden die snel oplopen, afhankelijkheden tussen componenten die lastig te managen zijn en ga zo maar door. En hoewel een stuk moderner geworden met C++11 loopt de taal op sommige gebieden nog steeds achter. Een mooi voorbeeld hiervan vormen enumeratietypes, of enums.
C++-enums zijn niet erg programmeurvriendelijk. Zo bevat de syntax voor het gebruik niet het type, wat de leesbaarheid niet ten goede komt. Er is ook geen standaard om enum-waardes te converteren van en naar een tekstuele representatie, wat vaak nodig is voor loggen en testdoeleinden. Hoewel enums in C++11 wel iets verbeterd zijn (je mag optioneel het type voor de waarde zetten), kan het nog beter. Om die reden hebben we bij Sioux voor een project op ons Development Center alle enums in de volgende vorm geschreven:
namespace Color
{
enum Enum
{
RED,
GREEN
};
std::vector<Enum> values();
std::string name(Enum e);
Enum valueOf(std::string str);
}
std::ostream& operator<<(std::ostream& os, const Color::Enum& e);
Bij deze aanpak moet je voor een waarde het type van de enum noemen, bijvoorbeeld ’currentColor = Color::RED‘ – een stuk leesbaarder. Verder retourneert de functie values een lijst met alle geldige enum-waardes, wat het makkelijk maakt om de enum te itereren met bijvoorbeeld de ’FOREACH‘ van Boost. De functies name en valueOf bieden de mogelijkheid waardes te converteren van en naar een tekstuele representatie. Kers op de taart is operator<<, waarmee enum-waardes direct naar een std::ostream zijn te schrijven. Deze aanpak lost een groot deel van onze enum-perikelen op. Minpuntje is dat je een variabele moet declareren als type Color::Enum.
