首页 > 编程语言 >如何获取C++中变量/表达式的类型

如何获取C++中变量/表达式的类型

时间:2022-09-04 22:15:33浏览次数:59  
标签:const 变量 int cout C++ include type 表达式 name

主要有三种方式:

  1. 使用 C++ 库自带的 typeid 函数;
  2. 使用 boost 库中 type_id_with_cvr 函数(末尾的 cvr 代表const, variable, reference);
  3. 自定义模板函数 type_name();

方式一:

        typeid 会把获取到的类型信息保存到一个 type_info 类型的对象里面,并返回该对象的常引用;当需要具体的类型信息时,可以通过成员函数来提取。

        不像 Java、C# 等动态性较强的语言,C++ 能获取到的类型信息非常有限,也没有统一的标准,如同“鸡肋”一般,大部分情况下我们只是使用重载过的“==”运算符来判断两个类型是否相同。

#include <typeinfo>
#include <iostream>
int main()
{
    int a = 100;
    const int b = 101;
    int& lref = a;
    int&& rref = std::move(a);

    std::cout << "int a:        type is    " << typeid(a).name() << std::endl;
    std::cout << "const int b:  type is    " << typeid(b).name() << std::endl;
    std::cout << "int& lref:    type is    " << typeid(lref).name() << std::endl;
    std::cout << "int&& rref:   type is    " << typeid(rref).name() << std::endl;
    return 0;
}

 可以发现:使用 typeid() 打印出来的类型不直观,并且它不支持引用类型的变量,也不能区分const变量。

 

方式二:

使用 boost 库中 type_id_with_cvr 函数(末尾的cvr代表const, variable, reference),这个方法打印出来的结果就比较优雅了(准确)

但需要下载 Boost 库,并编译安装,才能使用。

#include <iostream>
#include <boost/type_index.hpp>

int main()
{
    int a = 100;
    const int b = 101;
    int& lref = a;
    int&& rref = std::move(a);

    std::cout << "int a: type is " << boost::typeindex::type_id_with_cvr<decltype(a)>().pretty_name() << std::endl;
    std::cout << "const int b: type is " << boost::typeindex::type_id_with_cvr<decltype(b)>().pretty_name() << std::endl;
    std::cout << "int& lref: type is " << boost::typeindex::type_id_with_cvr<decltype(lref)>().pretty_name() << std::endl;
    std::cout << "int&& rref: type is " << boost::typeindex::type_id_with_cvr<decltype(rref)>().pretty_name() << std::endl;

    return 0;
}

输出结果:

int a: type is int
const int b: type is int const
int& lref: type is int&
int&& rref: type is int&&

 

方式二:

       定义了一个模板函数 type_name(),可以对传入的模板类型 T 进行类型判断,结合指针、左值/右值引用、常类型,准确得出变量的类型。在调用该函数时使用了decltype关键字,传入待确定的变量,然后输出变量类型。

#include <type_traits>
#include <typeinfo>
#include <memory>
#include <string>
#include <cstdlib>
#include <iostream>
#ifndef _MSC_VER
#include <cxxabi.h>
#endif

using namespace std;

template <class T>
string type_name()
{
    typedef typename remove_reference<T>::type TR;
    unique_ptr<char, void (*)(void *)> own(
#ifndef _MSC_VER
        abi::__cxa_demangle(typeid(TR).name(), nullptr, nullptr, nullptr),
#else
        nullptr,
#endif
        free);
    string r = own != nullptr ? own.get() : typeid(TR).name();
    if (is_const<TR>::value)
        r += " const";
    if (is_volatile<TR>::value)
        r += " volatile";
    if (is_lvalue_reference<T>::value)
        r += "&";
    else if (is_rvalue_reference<T>::value)
        r += "&&";
    return r;
}

int main()
{

     int a = 100;
     const int b = 101;
     int& lref = a;
     int&& rref = std::move(a);

     cout << "int a: type is " << type_name<decltype(a)>() << endl;
     cout << "const int b: type is " << type_name<decltype(b)>() << endl;
     cout << "int& lref: type is " << type_name<decltype(lref)>() << endl;
     cout << "int&& rref: type is " << type_name<decltype(rref)>() << endl;

}

结果如下:

 

标签:const,变量,int,cout,C++,include,type,表达式,name
From: https://www.cnblogs.com/czw-yibao/p/16656214.html

相关文章