Developer Tips
by Zhihao Yuan
Let’s say you want to model a game of rock paper scissors, where a hand is one of rock, paper, and scissors:
class rock {};
class paper {};
class scissors {};
using hand = std::variant<rock, paper, scissors>;
Ignoring the fact that this hand
type comes with heavily overloaded constructors and you can only add free functions, a troublesome issue is that the type-name std::variant<rock, paper, scissors>
will appear everywhere in debuggers and linkers in place of hand
.
A more flexible way is to define a new type for it:
struct hand : std::variant<rock, paper, scissors> {};
You may pass *this
directly to std::visit
without casting it to the base class type. And if you do need to refer to the base class type, you don’t have to type it again:
struct hand : std::variant<rock, paper, scissors>
{
static_assert(sizeof(variant) > 1);
Here, “variant
” is an injected-class-name in the class scope of hand
. It already aliases “std::variant<rock, paper, scissors>
.”