Алгебраические типы данных образуются из существующих в языке объединением и декартовым произведением. Первое в С++ имитируется boost::variant или наследованием (union в некоторых случаях), второе - любым кортежем или структурой.
Достаточно ограничить наследование [23.11] How can I set up my class so it won't be inherited from? и реализовать открытый список виртуальных функций через визитор.
Собственно я все порываюсь написать такой шаблончик, да лень. Может возьмешься?