I've having My
with an implicit ctor My(int i)
, I wish to cast an int into My, so I have:
#include <any>
#include <iostream>
using namespace std;
struct My {
My(int i) { cout << "int ctor\n"; }
};
ostream& operator << (ostream& os, const My& m) {
os << "My object\n";
return os;
}
int main() {
any a = 1;
auto am = My(any_cast<int>(a));
cout << a.type().name() << ": " << any_cast<int>(a) << '\n';
cout << a.type().name() << ": " << any_cast<My>(a) << '\n';
return 0;
}
Upon running, it prints:
int ctor
i: 1
i: terminate called after throwing an instance of 'std::bad_any_cast'
what(): bad any_cast
I expected that any_cast<My>(a)
should be able to call My(a)
to construct a new object, but actually not.
Did I mis-undertand anything?
CodePudding user response:
This is simply not how std::any_cast
works. It is not literally a cast between types like e.g. static_cast
is.
You must provide the exact type stored in the std::any
object to access its value (via std::any_cast
). It is impossible to imply any conversions.
Because the type stored in the std::any
is only determined at runtime, the compiler would need to emit code for every possible type that could be stored in it and be convertible to the target type, if implicit conversions were allowed. That is clearly infeasible or impossible.
There are only very few situations where std::any
is the right tool for the job. In particular it will not allow you to circumvent the statically-typed nature of C .
CodePudding user response:
As for the manual
Throws
std::bad_any_cast
if the typeid of the requestedT
does not match that of the contents of operand.
a
should contain the exact type My
.
I expected that any_cast(a) should be able to call My(a) to construct a new object, but actually not.
It does not call converting constructors.
CodePudding user response:
I expected that any_cast(a) should be able to call My(a) to construct a new object, but actually not.
No, any_cast<T>(a)
succeeds if and only if T
is present in a
. It answers the query whether there is T
in a
. Not whether there is some type implicitly convertible to T
. You have to do that after extracting the value yourself.