#include <iostream>
#include <any>
#include <string>
#include <vector>
#include <map>
using namespace std;
string AnyPrint(const std::any &value)
{
cout << size_t(&value) << ", " << value.type().name() << " ";
if (auto x = std::any_cast<int>(&value)) {
return "int(" std::to_string(*x) ")";
}
if (auto x = std::any_cast<float>(&value)) {
return "float(" std::to_string(*x) ")";
}
if (auto x = std::any_cast<double>(&value)) {
return "double(" std::to_string(*x) ")";
}
if (auto x = std::any_cast<string>(&value)) {
return "string(\"" (*x) "\")";
}
if (auto x = std::any_cast<char*>(&value)) {
return string(*x);
}
}
int main()
{
int a = 1;
float b = 2;
double c = 3;
string d = "4";
char *e = "555";
cout << AnyPrint(a) << "\n";
cout << AnyPrint(b) << "\n";
cout << AnyPrint(c) << "\n";
cout << AnyPrint(d) << "\n";
cout << AnyPrint("555") << "\n";
cout << AnyPrint(e) << "\n";
return 0;
}
I'm trying to make a function that converts a std::any
object to string, given that the list of possible types is hard-coded. However, there's a problem when user parse raw string like AnyPrint("555")
. I use the method from Checking std::any's type without RTTI
I got the following output when I run the program:
140722480985696, i int(1)
140722480985696, f float(2.000000)
140722480985696, d double(3.000000)
140722480985696, NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE string("4")
140722480985696, PKc string("4")
140722480985696, Pc 555
How can I handle a std::any
of raw string? I don't want to write AnyPrint("555"s)
unless it's the only way.
Edit: I use this to run the example https://www.onlinegdb.com/online_c _compiler
CodePudding user response:
Type of "555"
is const char[4]
which might decays to const char*
. You handle char*
, but not const char*
.
Handling const char*
fixes your issue:
std::string AnyPrint(const std::any &value)
{
std::cout << size_t(&value) << ", " << value.type().name() << " ";
if (auto x = std::any_cast<int>(&value)) {
return "int(" std::to_string(*x) ")";
}
if (auto x = std::any_cast<float>(&value)) {
return "float(" std::to_string(*x) ")";
}
if (auto x = std::any_cast<double>(&value)) {
return "double(" std::to_string(*x) ")";
}
if (auto x = std::any_cast<std::string>(&value)) {
return "string(\"" (*x) "\")";
}
if (auto x = std::any_cast<const char*>(&value)) {
return *x;
}
return "other";
}
CodePudding user response:
As mentioned in the comments, string literals like "555"
are (or decay to) const char*
pointers. Your AnyPrint
function doesn't handle such an argument type.
Adding the following block fixes the problem:
if (auto x = std::any_cast<const char*>(&value)) {
return string(*x);
}
Also, note that the line, char *e = "555";
is illegal in C ; you need either const char *e = "555";
or char e[] = "555";
; using the latter will demonstrate the difference between the char*
(with AnyPrint(e)
) and const char*
(with AnyPrint("555")
) types in the std::any_cast<T>
blocks.