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