@Arthur
Thanks Arthur!

I am watching your videos as soon as you post them :)

@all

I can see that the idea for storing numbers e.g. floats / doubles / ints can not be possible, because the "internal" type is not known.

Extracting base class would work, if std::any holds child class, but only when single inheritance is made.
However this is implementation detail so the fact it works for a specific compiler does not mean it will always work.
It will NOT work with multiple inheritance. this example returns garbage:

// https://gcc.godbolt.org/z/zG87Tz

struct X{
virtual int xprocess() = 0;
};

struct A{
virtual int process() = 0;
};

struct B : X, A{
int process() override{
return 5;
}

int xprocess() override{
return 54;
}
};

int main(){
B b;

void *v = &b;

auto *x = (A *) v;
// this would be correct
//auto *x = (A *) (B *) v;

return x->process();
}




On Sat, Dec 5, 2020 at 11:21 PM Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrote:
On Sat, Dec 5, 2020 at 3:49 PM connor horman via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Sat, Dec 5, 2020 at 14:31 Nikolay Mihaylov via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Consider following code:

    struct A{
      virtual ~A() = default;
      virtual int op(int a, int b) const = 0;
    };
   
    struct Sum : A{
        int op(int a, int b) const override{
            return a + b;
        }
    };
   
    #include <any>
   
    std::any x = Sum{};
   
    int main(){
        return std::any_cast<A &>(x).op(5, 5);
    }

It crashes with `std::bad_any_cast` exception. [...]
Maybe we need some other kind of cast, for example std::non_secure_any_cast that just casts the value no matter what.

You need to distinguish between different kinds of "casts." Some are physically possible to implement; some aren't.
For example, it's trivial to implement a reinterpret_any_cast<T>. But that won't help you in situations like

struct A { int i = 1; };
struct B { int j = 2; };
struct C : A, B { int k = 3; };
std::any x = C{};
int main() { return reinterpret_any_cast<B&>(x).j; }  // returns 1, not 2

It's also possible to implement a dynamic_any_cast, exploiting the special fact that std::any always owns its contents and therefore knows (at construction time) the most derived type of the contained object. For this implementation, see the worked example in "Back to Basics: Type Erasure" (CppCon 2019); and for the detailed semantics of dynamic_cast and the significance of knowing the most derived type, see "dynamic_cast from scratch" (CppCon 2017).  However, dynamic_cast works only on polymorphic types.

struct A { int i = 1; };
struct B { int j = 2; virtual ~B(); };
struct C : A, B { int k = 3; };
std::any x = C{};
int main() { return dynamic_any_cast<B&>(x).j; }  // OK, returns 2

However, from your motivation, it seems like you are really asking for the ability to do, like,

std::any x = 3.14;
int main() { return static_any_cast<float>(x); } // could this return 3.14f? NO!

and that's simply physically impossible. (Again, see "Back to Basics: Type Erasure" for the details.)

HTH,
–Arthur