是否可以在 C++ 中存储类型?

Is it possible to store a type in C++?

有没有简单的方法来保持变量的类型?

例如,存储在通用容器 std::map<key, std::any> myMap; 中会将值类型转换为 std::any,并且会忘记初始类型。如果只是以某种方式将类型存储为 std::string,然后将其与 typeid(someType).name() 进行比较。但是这样恢复类型好像很不方便

自己有一些存储类型的功能似乎很有用:

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

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

你应该考虑std::variant。一个变体分配一个隐藏的整数作为每个允许类型的枚举器。

这与解释型语言为您提供的存储类型的能力并不完全相同。但是,存储真正的“任何”类型有多大用处值得怀疑。一个值是不好的,除非你可以对其进行一些操作。为了操作一个值,你必须知道它是什么类型。

举个例子,您可能希望存储值,然后对它们求和。您不想假设值是什么类型,因此您使用存储任何类型的“魔术”任何类型。您的代码现在可以添加 int/float/char/etc。数字和字符串的结果是什么?也许你做大多数解释性语言所做的并将数字转换为字符串。这是你的意思吗?可能是? 然而,int+Widget 的值是多少呢?这还有意义吗?解释性语言会给您带来 运行 时间错误。 C++ 想在编译时给你错误。 如果您使用 Variant,您实际上是在定义一个应该给出合理结果的类型列表,如果任何类型组合的“+”定义不正确,那么代码将不会构建,但另一方面您永远无法获得运行 时间错误。 请参阅下面的代码作为示例。

#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;
}

如果你只需要检查std::any中存储值的当前类型是否是某种类型,你可以使用std::any::type():

#include <any>
#include <cassert>
#include <typeinfo>

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));
}