Home > Enterprise >  C 17 "any_cast" fail for implicit ctor, throws exception
C 17 "any_cast" fail for implicit ctor, throws exception

Time:06-29

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 requested T 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.

  • Related