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.
this happens, because std::any_cast is specified in terms of typeid.
I also know how to fix this.
However I can not understand why this
should happen. Reference is pointer under the hood, so cast should work, e.g. following works OK.
This isn't necessarily the case, but even when it is, pointers are quite interesting and not simply addresses.
Maybe we need some other kind of cast, for example std::non_secure_any_cast that just casts the value no matter what.
I wouldn't think this necessarily fixes this, due to strict-aliasing. Notably, reinterpret_casting a pointer to Sum to a pointer to A wouldn't necessarily yield a pointer to the A subobject of the Sum, because it's not pointer-interconvertible. I am not saying its not a good idea, I think an unchecked version of "any_cast" may be useful, but it won't solve the problem you brought up.
We can not really call it "dynami_any_cast", because it will work the same way for int -> long or unsigned -> float.
Those conversions would be impossible to do without violating strict-aliasing. Focusing on the dynamic_any_cast case may work better, especially since the proposed operation would not solve your original problem, as I mentioned.
Of course the price if we made the wrong cast the program will crash, but I can make the program crash with the current std::any_cast implementation as well.
Current std::any_cast does not behave the way programmers expect:
Consider this code:
int main(){
Sum s;
A &a = s;
return a.op(5, 5);
}
and this code too:
int main(){
Sum s;
A *a = &s;
return a->op(5, 5);
}
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals