Skip to content
Future C++ implementation of Rust-like trait objects with no boilerplate
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
LICENSE Initial commit Aug 22, 2017 Working version Aug 8, 2019
example.cpp Correct version Aug 8, 2019

Typeclasses in C++

This is an idea of how Rust-like trait objects could be implemented in C++ using static reflection, code injection and metaclasses. This solution is very succinct, requiring no boilerplate or arcane tricks. It has been tested against the Clang fork at 02eaac5aa06dfa0d19de95270bccd6311f11f5ba.

The idea is to use class definitions which have only declarations of members as typeclasses. For example, a typeclass which is satisfied by classes with a print function which returns nothing and takes no arguments can be defined as follows:

class(typeclass) printable {
    void print();

The typeclass metaclass will generate a class which can be constructed from values of any type satisfying the interface. The given object will be type-erased and forwarding functions will be generated to call the relevant functions on the implementation.

Say that we have a couple of classes which fulfil this interface:

struct foo {
    void print() { std::cout << "foo"; }

struct bar {
    void print() { std::cout << "bar"; }

We can type-erase these objects by using printable:

printable a = foo{};
printable b = bar{};

We could even store them in a container:

std::vector<printable> v;

Or reassign from different types:

printable a = foo{};
a = bar{};

As support in the compiler progresses, I'll think about adding opt-in features, or C++11-concepts-style concept maps.

See Sean Parent's talks on Inheritance is the Base Class of Evil and Value Semantics and Concepts-based Polymorphism for some of the motivation behind this. See Dyno and Boost.TypeErasure for other implementations.

You can’t perform that action at this time.