C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Language support for type erasure

From: Nikl Kelbon <kelbonage_at_[hidden]>
Date: Fri, 10 Apr 2026 17:31:09 +0500
Its already exists https://github.com/kelbon/AnyAny

пт, 10 апр. 2026 г. в 14:39, Frederick Virchanza Gotham via Std-Proposals <
std-proposals_at_[hidden]>:

> In a job interview recently I was given the following code:
>
> #include <iostream>
> #include <memory>
> #include <string>
>
> struct Animal {
> virtual ~Animal() = default;
> virtual std::string name() const = 0;
> };
>
> struct Cat : Animal {
> std::string name(void) const override
> {
> return "Cat";
> }
> };
>
> struct Dog : Animal {
> std::string name(void) const override
> {
> return "Dog";
> }
> };
>
> /* DO NOT CHANGE THE CODE BELOW! */
>
> void print_name(Animal const &a)
> {
> std::cout << a.name() << std::endl;
> }
>
> int main(void)
> {
> Cat cat;
> Dog dog;
> print_name(cat);
> print_name(dog);
> }
>
> I was told to remove the inheritance, but I wasn't allowed to edit
> code beneath the indicated line. So here's what I gave them back:
>
> struct Cat {
> string name(void) const
> {
> return "Cat";
> }
> };
>
> struct Dog {
> string name(void) const
> {
> return "Dog";
> }
> };
>
> struct Animal {
> std::function< string(void) > name;
>
> template<typename T>
> Animal(T &&arg)
> {
> name = [&arg](void){ return arg.name(); };
> }
> };
>
> Now let's consider if there were multiple member functions:
>
> struct Cat {
> string name(void) const
> {
> return "Cat";
> }
> string weight(void) const
> {
> return "4kg";
> }
> string height(void) const
> {
> return "20cm";
> }
> };
>
> struct Dog {
> string name(void) const
> {
> return "Dog";
> }
> string weight(void) const
> {
> return "12kg";
> }
> string height(void) const
> {
> return "50cm";
> }
> };
>
> struct Animal {
> std::function< string(void) > name;
> std::function< string(void) > weight;
> std::function< string(void) > height;
>
> template<typename T>
> Animal(T &&arg)
> {
> name = [&arg](void){ return arg.name (); };
> weight = [&arg](void){ return arg.weight(); };
> height = [&arg](void){ return arg.height(); };
> }
> };
>
> Instead of having multiple functor objects, we could do something like:
>
> struct Animal {
> std::function< string(unsigned) > f;
>
> template<typename T>
> Animal(T &&arg)
> {
> f =
> [&arg](unsigned const n) -> string
> {
> switch ( n )
> {
> case 0: return arg.name ();
> case 1: return arg.weight();
> case 2: return arg.height();
> }
> };
> }
>
> string name (void) const { return f(0); }
> string weight(void) const { return f(1); }
> string height(void) const { return f(2); }
> };
>
> This got me thinking . . . . Should we have native language support for
> this?
> For example let's say we were to define a class with the interface that we
> want:
>
> struct Interface {
> string name(void) const;
> string weight(void) const;
> string height(void) const;
> };
>
> And then perhaps we would have a new kind of 'typedef' that creates
> the type-erased class, something like:
>
> typedef<Interface> TypeErasedType;
>
> And so then the entire program would look something like this:
>
> #include <iostream>
> #include <functional>
> #include <string>
> #include <utility>
> using std::string;
>
> struct Cat {
> string name(void) const
> {
> return "Cat";
> }
> string weight(void) const
> {
> return "4kg";
> }
> string height(void) const
> {
> return "20cm";
> }
> };
>
> struct Dog {
> string name(void) const
> {
> return "Dog";
> }
> string weight(void) const
> {
> return "12kg";
> }
> string height(void) const
> {
> return "50cm";
> }
> };
>
> struct Interface {
> string name(void) const;
> string weight(void) const;
> string height(void) const;
> };
>
> typedef<Interface> Animal;
>
> /* DO NOT CHANGE THE CODE BELOW! */
>
> void print_name(Animal const &a)
> {
> std::cout << a.name () << std::endl;
> std::cout << a.weight() << std::endl;
> std::cout << a.height() << std::endl;
> }
>
> int main()
> {
> Cat cat;
> Dog dog;
> print_name(cat);
> print_name(dog);
> }
>
> Another nice thing about this is that we would get a very intuitive
> compiler warning if the supplied type doesn't fulfil all the criteria
> of the type-erased type -- it can clearly tell us that the supplied
> type is missing a member function that's required for the interface.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2026-04-10 12:31:26