【问题标题】:How do I get the type of a variable?如何获取变量的类型?
【发布时间】:2012-07-03 21:13:08
【问题描述】:

在 C++ 中,如何找到变量的类型?

【问题讨论】:

标签: c++ variables typeof


【解决方案1】:

如果你需要对一个类和一个已知类型进行比较,例如:

class Example{};
...
Example eg = Example();

您可以使用这条比较线:

bool isType = string( typeid(eg).name() ).find("Example") != string::npos;

检查typeid 名称是否包含字符串类型(typeid 名称有其他损坏的数据,因此最好使用s1.find(s2) 而不是==)。

【讨论】:

    【解决方案2】:

    您绝对可以选择typeid(x).name(),其中 x 是变量名。它实际上返回一个指向数据类型的 const char 指针。现在,看看下面的代码。

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n = 36;
        char c = 'A';
        double d = 1.2;
        if(*(typeid(n).name()) == 'i'){
            cout << "I am an Integer variable" << endl;
        }
        if(*((char *) typeid(d).name()) == 'd'){
            cout << "I am a Double variable" << endl;
        }
        if(*((char *) typeid(c).name()) == 'c'){
            cout << "I am a Char variable" << endl;
        }
        return 0;
    }
    

    注意 first 和 second 是如何工作的。

    【讨论】:

    • 通过第一个字符识别类型是一个非常糟糕的主意。
    • 请您说得更具体一点,德米特里?我没明白你的意思。
    • 这可以缩短为std::cout &lt;&lt; "I'm a variable of type " &lt;&lt; typeid(n).name()。 (重新措辞以防止出现伪影,但这可以通过另一次检查来修复)。即使那样,如果您绝对想要比较,最好还是typeid(n) == typeid(int)
    【解决方案3】:

    对于静态断言,C++11 引入了decltype,在某些场景下非常有用。

    【讨论】:

    • decltype 不仅可以用于静态断言。例如,decltype(a) b;b 声明为与 a 相同的类型。
    【解决方案4】:

    你可以使用the typeid operator:

    #include <typeinfo>
    ...
    cout << typeid(variable).name() << endl;
    

    【讨论】:

    【解决方案5】:

    我不确定我的回答是否有帮助。

    简短的回答是,您实际上并不需要/不想知道变量的类型来使用它。

    如果您需要为静态变量指定类型,那么您可以简单地使用 auto。

    在更复杂的情况下,您想在类或结构中使用“auto”,我建议使用带有 decltype 的模板。

    例如,假设您正在使用其他人的库,并且它有一个名为“unknown_var”的变量,并且您希望将其放入向量或结构中,您完全可以这样做:

    template <typename T>
    struct my_struct {
        int some_field;
        T my_data;
    };
    vector<decltype(unknown_var)> complex_vector;
    vector<my_struct<decltype(unknown_var)> > simple_vector
    

    希望这会有所帮助。

    编辑:为了更好地衡量,这是我能想到的最复杂的情​​况:拥有一个未知类型的全局变量。在这种情况下,您需要 c++14 和模板变量。

    类似这样的:

    template<typename T> vector<T> global_var;
    
    void random_func (auto unknown_var) {
        global_var<decltype(unknown_var)>.push_back(unknown_var);
    }
    

    这仍然有点乏味,但它已经尽可能接近无类型语言了。只要确保每当你引用模板变量时,总是把模板规范放在那里。

    【讨论】:

      【解决方案6】:

      如果你有一个变量

      int k;
      

      您可以使用

      获取其类型
      cout << typeid(k).name() << endl;
      

      在 SO 上查看以下主题:Similar question

      【讨论】:

        【解决方案7】:

        我相信我有一个使用 typeid() 的有效用例,就像使用 sizeof() 一样有效。对于模板函数,我需要根据模板变量对代码进行特殊处理,以便提供最大的功能和灵活性。

        为每种支持的类型创建一个函数实例,比使用多态更加紧凑和可维护。即使在那种情况下,我也可能使用这个技巧只编写一次函数体:

        请注意,由于代码使用模板,下面的 switch 语句应该静态解析为一个代码块,优化所有错误情况,AFAIK。

        考虑这个例子,如果 T 是一种类型而不是另一种类型,我们可能需要处理转换。我将它用于类专业化以访问硬件将使用 myClassA 或 myClassB 类型的硬件。在不匹配的情况下,我需要花时间转换数据。

        switch ((typeid(T)) {
          case typeid(myClassA):
            // handle that case
            break;
          case typeid(myClassB):
            // handle that case
            break;
          case typeid(uint32_t):
            // handle that case
            break;
          default:
            // handle that case
        }
        

        【讨论】:

        • TypeId:我无法在 Arduino 上使用 typeid()。 typeid() 也是 runtime 检查,而不是编译时检查,因此不能用于生成优化代码。
        • 是的,不,这与您想象的不一样。 typeid 根本不可能是静态的编译时检查 - 根据定义 - 所以这不利于任何优化。 For a template function, I need to special case the code based on the template variable 对,所以你真正想要的是通过 CRTP 成语实现的静态多态性。这正是实现的目标。
        • @Dan 那是因为typeid() 依赖于RTTI,这并不是在所有平台上都能保证的。
        【解决方案8】:

        C++ 和 Javascript 的主要区别在于 C++ 是一种静态类型的语言,而 javascript 是动态的。

        在动态类型语言中,变量可以包含任何东西,并且它的类型由它所持有的值给出,每时每刻。 在静态类型语言中,变量的类型是声明的,并且不能更改。

        可以有动态分派和对象组合和子类型(继承和虚函数)以及静态分派和超类型(通过模板 CRTP),但无论如何编译器必须知道变量的类型。

        如果您不知道它是什么或可能是什么,那是因为您设计了一些东西,因为该语言具有动态类型系统。

        如果是这种情况,您最好重新考虑您的设计,因为它会进入一个不适合您使用的语言的土地(最像带着毛毛虫在高速公路上行驶,或者带着汽车在水中行驶)

        【讨论】:

        • 如果 C++ 有动态变化,那么我认为它会很棒,typeof 和 parseInt,parseFloat 函数也会派上用场,但我不知道为什么 C++ 制造商让它变得太难,例如!谁说写 cout 好
        • 决心是最好的!!!! #include 字符串 str("1912"); int strtointval; stringstream(str) >> strtointval;
        • @Waqas 呃,什么?说它最好的人是定义语言的人,而 IMO 他们几乎对与它有关的任何事情都有最终决定权——例如,良好的编码实践。您能否改写该评论以使其更有意义?
        • 我完全不同意。 Java、C#、PHP、Perl、Python 等都是用 C 和 C++ 设计的,它们不是毛毛虫。 (当您创建数据库应用程序以从“未知”数据库中打开变量表时,您需要以“非常”动态的方式控制字段类型到变量方案,反之亦然;)
        • @TomeeNS:不。它们是用 C 和 C++编写,而不是设计。它们旨在完成工作。即使 C 和 C++ 本身没有,它们也具有动态类型。这并不奇怪。
        【解决方案9】:

        通常,想要在 C++ 中查找变量的类型是错误的问题。它往往是您从诸如 C 或 Pascal 之类的过程语言中携带的东西。

        如果您想根据类型编写不同的行为,请尝试了解例如function overloadingobject inheritance。在您使用 C++ 的第一天,这不会立即生效,但请坚持下去。

        【讨论】:

        • 不是真的,假设你有一个类 Object 和一个子类 Book。现在假设您有一个可以存储大量对象的 Box,但出于某种原因,您想列出其中的所有 Books。检查类型要干净得多,然后必须向 Object 添加一个方法“type”,然后在 Book 上覆盖它以返回类似“book”的内容
        • 与任何规则一样,也有例外(因此我的'通常'!),容器确实倾向于增加类型理论的复杂性。我从来没有过分喜欢多态对象的容器……在大多数情况下,模板化的统一容器类型就足够了,而且更干净。
        • 你不使用模板吗?
        【解决方案10】:
        #include <typeinfo>
        
        ...
        string s = typeid(YourClass).name()
        

        【讨论】:

          猜你喜欢
          • 2016-12-03
          • 2014-08-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-21
          相关资源
          最近更新 更多