Home > Enterprise >  Is it possible to store a type in C ?
Is it possible to store a type in C ?

Time:10-06

Is there any easy way to keep the type of variable?

For example storing in general container std::map<key, std::any> myMap; will cast values types to std::any, and init types will be forgotten. If only somehow to store type as a std::string, and then compare it with typeid(someType).name(). But it seems realy inconvenient to restore types in such manner.

It seems pretty useful to have some functional of storing type by itself:

type my_type = int; // or any other type
my_type data = ...;

std::map<key, std::pair<type, std::any>> myMap;

CodePudding user response:

You should consider std::variant. A variant assigns a hidden integer to be an enumerator for each allowed type.

This is not quite the same ability as an interpreted language would give you to store a type. However, it is questionable how useful storing a real "any" type would be. A value is no good unless you can do some operation on it. In order to manipulate a value, you must know what type it is.

Take an example, you may wish to store values and then sum them. You don't want to assume what types the values are, so you use a "magic" any type that stores any type. Your code can now add int/float/char/etc. What though is the result of a number and string? Maybe you do what most interpreted languages do and convert the number to string. Is that what you meant? Maybe? However, what is the value of int Widget? Is this even meaningful? An interpreted language would give you a runtime error. C wants to give you errors at compile time. If you use a Variant you are effectively defining a list of types which should give reasonable results, if any of the combination of types is ill defined for " ", then the code will not build, but on the other side you can never get a run-time error. See the code below as an example.

#include <variant>
#include <vector>
using Value = std::variant<char, unsigned char, short, unsigned short, int, unsigned, float, double>;

Value Sum(std::vector<Value>& values)
{
    Value sum = (int)0;
    for (const auto& v: values)
        sum  = std::visit([v](auto c_sum)
                  { return std::visit([c_sum](auto c_v)
                    { 
                      return Value{c_sum c_v};
                    }
                   ,v);}
            ,sum);
    return sum;
}

CodePudding user response:

If you just need to check if the current type of the stored value in an std::any is a certain type, you could use std::any::type():

#include <any>
#include <cassert>

int main()
{
    std::any foo;
    assert(foo.type() == typeid(void));
    foo = 1;
    assert(foo.type() == typeid(int));
    foo = 1.23;
    assert(foo.type() == typeid(double));
}
  • Related