C++ how to use std::any_cast and avoid else if statements
First, this call to __cxa_demangle returns a buffer allocated with malloc and which must be freed. This isn't freed, so this code has a memory leak.

Second, as I understand it, __cxa_demangle does not exist in MSVC, so this is not portable.

Third, the .find("string") catches more than std::string. It would match std::wstring, std::stringstream, void (*)(std::string).

Fourth, this code relies essentially on knowing the potential types that are in that std::any. That is knowledge at a distance, and if you allow more types at the place of construction, you need more types here.

Fifth, if the type isn't one of those types, the error is silent and the output is the type contained, not the value. That could be harmless, but it could be a real problem. If you allowed type Foo in the any, and neglected to update this location, you wouldn't be able to tell if the output Foo was that type name or the value of a string stored in the any.

The suggestion of the other answer is to constrain the types stored using the type storing them. Instead of any use std::variant&lt;std::string, long long, unsigned long long, double&gt;. I added the string and unsigned options relative to the other answer. Then just visit:

std::visit([&amp;](const auto&amp; value) { out &lt;&lt; value; }, n.value);


This is a very strong option.

A second option would be to erase not almost every aspect of the type (as with std::any) but instead leave the interface you need, e.g. erase everything but the stream operator if that's all you need:

    printable p = 2.3;
    std::cout &lt;&lt; p &lt;&lt; "\n";
    p = "foo";
    std::cout &lt;&lt; p &lt;&lt; "\n";


Example: https://godbolt.org/z/NtJqWk

(edit: added a missing virtual destructor to impl_base)