How about adding one or more exercises on type erasure?

Recently I’ve published a 3-parts series on YouTube to explain type erasure in C++ via implementing a toy version of std::any (the meaty part is part 2, here).

I think I could make an exercise where the user has to implement the key (and difficult) parts of std::any from an existing skeleton.

I think that’s very valuable, because while type-erasure is not something you make use of on a daily bases, understanding it deeply means understanding some aspects of the language very deeply, and that’s very important.

What do people think?

What do the track maintainers think? :wink:

This seems like an advanced concept, after “templates” and maybe a vanilla “polymorphism” with virtual functions, etc.

1 Like

Not a C++ maintainer, but it would probably be useful to see code for a possible test suite and solution.

Where are the advanced concepts? I’ve found C++ key concepts on Exercism, but there’s no “template” or “polymorphism” node.

But yes, type-erasure in C++ is a very complex topic, though it’s as old as it can be.

But I firmly believe that working out how to implement std::any from scratch is an effective way to understand the heart of it and, in turn, to understand some aspects of C++ that would otherwise be never so easy to grasp.

It would not be a single exercise, but a series, building on top of each other.

The first one could be this:

Define a class called Any in such a way that an object of this class is constructible from objects of any type

The initial code could be just empty.

The test would be like this

int main() {
    // test that Any is initializable from any type
    Any i = 3;
    Any v = std::vector<int>{};
    Any l = []{}; // including the untypeable type of a lambda

    // test that Any is a hard type, not a template
    static_assert(std::is_same_v<decltype(i), decltype(v)>);
    static_assert(std::is_same_v<decltype(i), decltype(l)>);
}

and that would essentially ensure that they have written a non-template class with a templated constructor, rather than a template class or anything else.

This is the first step towards a implementation of std::any.

A second step could start from this code:

struct Any {
    template<typename T>
    requires std::is_lvalue_reference_v<T>
    Any(T&& t)
        : payload{/* choose initializer here */}
    {}

    template<typename T>
    friend T const* AnyCast(Any& a) {
        return static_cast<T const*>(a.payload);
    }
  private:
    /* chose type here */ payload;
};

and ask to declare the payload member variable and initialize it appropriately in the constructor in such a way that AnyCast, if given the type that was passed to Any’s constructor, returns the pointer to that very object.

The test would be along these lines

int main() {
    int i{3};
    std::vector<int> v{};
    auto l = []{};
    // test that Any is initializable from any type
    Any ai = i;
    Any av = v;
    Any al = l; // including the untypeable type of a lambda

    // test that Any is a hard type, not a template
    static_assert(std::is_same_v<decltype(ai), decltype(av)>);
    static_assert(std::is_same_v<decltype(ai), decltype(al)>);

    assert(&i == AnyCast<int>(ai));
    assert(&v == AnyCast<std::vector<int>>(av));
    assert(&l == AnyCast<decltype(l)>(al));
}

and would make sure that they have indeed stored a pointer to the object passed to the constructor, and if they have done so, they must have used void*, which is at the heart of type-erasure in C++.

And following exercise would go on like this.

That’s what I mean. Exercises which aim to teach a specific subject are usually concept exercises. They are associated with a concept (the subject being taught) and organized in a tree, from easier/basic concepts to harder/complex ones.

In order to teach type erasure in CPP, you’d probably need one polymorphism and one template concept before it. Those are not in the current syllabus yet, although I believe @vaeng have them planned.

Apart from concept exercises, which aim to teach one specific subject, there are also practice exercises. But they should usually be solvable in many ways and not be attached to a specific subject.

2 Likes

Thanks for the terminology explanation. I suppose what I’ve described is a “concept exercise”.

Regarding the link you’ve posted, it’s from July 2023… I’d assume no ongoing work exists.

Hi @Aster89 :wave:

Wanted to chime in here to say that as a (very) casual C++ learner, this post sent me down a wonderful rabbit hole this morning that had me jumping from C++ to Java to Rust and more. I think the topic of type-erasure (if it could be broken down in a series and explained well) would be a great addition to the C++ syllabus (the set of concept exercises for the track).

However, I strongly agree with @oxe-b that it would need some very clear prerequisite exercises, and that the C++ syllabus on the whole needs more fleshing out with other less complex topics. That doesn’t mean you must wait, but it does mean that this topic and cluster of exercises would then be quite disconnected from the rest of the syllabus until the intermediary topics could be fleshed out. Ultimately, it would be the track maintainers who would make the call on what to prioritize/make public.


Sometimes work is slow on a Syllabus, due to maintainer time and community energy. Case in point: Python’s Syllabus should be much larger, but the maintainer (me) is very very slow. That doesn’t mean thought and work have halted. It means that maintainers are volunteers, and their available time fluctuates radically. Since maintainers are also responsible for tooling and language upgrades, it can also look like no work is happening when its actually happening … elsewhere. :slightly_smiling_face:

3 Likes

this post sent me down a wonderful rabbit hole

Thanks for the feedback! I’m glad you found the rabbit hole entertaining!

this topic and cluster of exercises would then be quite disconnected from the rest of the syllabus until the intermediary topics could be fleshed out. Ultimately, it would be the track maintainers who would make the call on what to prioritize/make public.

Well I could start from there, and then try to fill the gaps backwards, or in another order.

1 Like

I am sure that the maintainers would warmly welcome the work (especially if you looped back to fill in gaps :smile:), provided it aligns with what they intended to cover.

I think the next steps for you would be to get familiar with how concept write-ups and concept exercises work: concepts, concept exercises, syllabus, and concept maps.

Optionally, you could also familiarize yourself with how the C++ test runner works, and what others have done for tests for a concept exercise on the track. You can look at concept exercises for C++ here and concept write-ups here

My advice would be to start simple and either do a quick draft, or an outline of what the concept breakdown would be, and what a concept exercise would look like. It would be important to include possible tasks for a student going through that concept exercise, as well as one or more tests.

Since this is an advanced and complicated topic, it might also be good to provide a list of what you think the progression would be from the last topic in the current Syllabus to your proposed topic(s).

Then I’d come back here and start a discussion with the maintainers about your proposed concept(s) and concept exercise(s).

You can draft up a PR - but we typically ask potential contributors to discuss things here and get maintainer buy-in before doing too much work, so that we avoid frustration.

cc-ing the CPP maintainers: @siebenschlaefer @vaeng @ahans

1 Like