Search code examples
c++stringc-stringsrttistdany

C++ std::any function that convert std::any of C char-array to string


#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


Solution

  • 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";
    }
    

    Demo