例如:

int a = 12;
cout << typeof(a) << endl;

预期的输出:

int

当前回答

在c++ 11中,我们有decltype。在标准c++中,没有办法显示使用decltype声明的变量的确切类型。我们可以使用boost typeindex,即type_id_with_cvr (cvr代表const, volatile, reference)来打印如下所示的类型。

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

using namespace std;
using boost::typeindex::type_id_with_cvr;

int main() {
  int i = 0;
  const int ci = 0;
  cout << "decltype(i) is " << type_id_with_cvr<decltype(i)>().pretty_name() << '\n';
  cout << "decltype((i)) is " << type_id_with_cvr<decltype((i))>().pretty_name() << '\n';
  cout << "decltype(ci) is " << type_id_with_cvr<decltype(ci)>().pretty_name() << '\n';
  cout << "decltype((ci)) is " << type_id_with_cvr<decltype((ci))>().pretty_name() << '\n';
  cout << "decltype(std::move(i)) is " << type_id_with_cvr<decltype(std::move(i))>().pretty_name() << '\n';
  cout << "decltype(std::static_cast<int&&>(i)) is " << type_id_with_cvr<decltype(static_cast<int&&>(i))>().pretty_name() << '\n';
  return 0;
}

其他回答

Howard Hinnant使用魔法数字提取类型名称。康桓瑋建议字符串前缀和后缀。但是前缀/后缀一直在变化。 使用" probe_type " type_name自动计算" probe_type "的前缀和后缀大小,以提取类型名称:

#include <string_view>
using namespace std;

namespace typeName {
 template <typename T>
  constexpr string_view wrapped_type_name () {
#ifdef __clang__
    return __PRETTY_FUNCTION__;
#elif defined(__GNUC__)
    return  __PRETTY_FUNCTION__;
#elif defined(_MSC_VER)
    return  __FUNCSIG__;
#endif
  }

  class probe_type;
  constexpr string_view probe_type_name ("typeName::probe_type");
  constexpr string_view probe_type_name_elaborated ("class typeName::probe_type");
  constexpr string_view probe_type_name_used (wrapped_type_name<probe_type> ().find (probe_type_name_elaborated) != -1 ? probe_type_name_elaborated : probe_type_name);

  constexpr size_t prefix_size () {
    return wrapped_type_name<probe_type> ().find (probe_type_name_used);
  }

  constexpr size_t suffix_size () {
    return wrapped_type_name<probe_type> ().length () - prefix_size () - probe_type_name_used.length ();
  }

  template <typename T>
  string_view type_name () {
    constexpr auto type_name = wrapped_type_name<T> ();

    return type_name.substr (prefix_size (), type_name.length () - prefix_size () - suffix_size ());
  }
}

#include <iostream>

using typeName::type_name;
using typeName::probe_type;

class test;

int main () {
  cout << type_name<class test> () << endl;

  cout << type_name<const int*&> () << endl;
  cout << type_name<unsigned int> () << endl;

  const int ic = 42;
  const int* pic = &ic;
  const int*& rpic = pic;
  cout << type_name<decltype(ic)> () << endl;
  cout << type_name<decltype(pic)> () << endl;
  cout << type_name<decltype(rpic)> () << endl;

  cout << type_name<probe_type> () << endl;
}

输出

gcc 10.2:

test
const int *&
unsigned int
const int
const int *
const int *&
typeName::probe_type

铿锵声11.0.0:

test
const int *&
unsigned int
const int
const int *
const int *&
typeName::probe_type

VS 2019版本16.7.6:

class test
const int*&
unsigned int
const int
const int*
const int*&
class typeName::probe_type

一个没有函数重载的更通用的解决方案:

template<typename T>
std::string TypeOf(T){
    std::string Type="unknown";
    if(std::is_same<T,int>::value) Type="int";
    if(std::is_same<T,std::string>::value) Type="String";
    if(std::is_same<T,MyClass>::value) Type="MyClass";

    return Type;}

这里的MyClass是用户定义的类。这里还可以添加更多的条件。

例子:

#include <iostream>



class MyClass{};


template<typename T>
std::string TypeOf(T){
    std::string Type="unknown";
    if(std::is_same<T,int>::value) Type="int";
    if(std::is_same<T,std::string>::value) Type="String";
    if(std::is_same<T,MyClass>::value) Type="MyClass";
    return Type;}


int main(){;
    int a=0;
    std::string s="";
    MyClass my;
    std::cout<<TypeOf(a)<<std::endl;
    std::cout<<TypeOf(s)<<std::endl;
    std::cout<<TypeOf(my)<<std::endl;

    return 0;}

输出:

int
String
MyClass

考虑下面的代码:

#include <iostream>

int main()
{
    int a = 2; // Declare type "int"
    std::string b = "Hi"; // Declare type "string"
    long double c = 3438; // Declare type "long double"
    if(typeid(a) == typeid(int))
    {
        std::cout<<"int\n";
    }

    if(typeid(b) == typeid(std::string))
    {
        std::cout<<"string\n";
    }
    
    if(typeid(c) == typeid(long double))
    {
        std::cout<<"long double";
    }
    return 0;
}

我相信你想要整个单词(而不是只打印int的缩写形式(即I),你想要int),这就是为什么我做了if。

对于一些变量(字符串,long double等…)比较它们的简写形式不会输出预期的结果),您需要将应用typeid操作符的结果与特定类型的typeid进行比较。

从cppreference:

返回一个实现定义的以空结束的字符串,包含类型的名称。不提供任何保证;特别地,返回的字符串对于多个类型是相同的,并且在同一个程序的调用之间会发生变化。


在我看来,Python在这种情况下比c++更好。Python有内置的type函数,可以直接访问变量的数据类型。

涉及RTTI (typeid)的其他答案可能是您想要的,只要:

您可以承担内存开销(对于某些编译器,这可能相当大) 编译器返回的类名很有用

另一种选择(类似于Greg Hewgill的答案)是建立一个特征的编译时表。

template <typename T> struct type_as_string;

// declare your Wibble type (probably with definition of Wibble)
template <>
struct type_as_string<Wibble>
{
    static const char* const value = "Wibble";
};

注意,如果你将声明包装在宏中,你将在声明带有多个参数的模板类型时遇到麻烦(例如std::map),这是由于逗号的原因。

要访问变量类型的名称,您所需要的是

template <typename T>
const char* get_type_as_string(const T&)
{
    return type_as_string<T>::value;
}

不要忘记包含<typeinfo>

我相信您所指的是运行时类型标识。你可以通过做来达到以上目的。

#include <iostream>
#include <typeinfo>

using namespace std;

int main() {
  int i;
  cout << typeid(i).name();
  return 0;
}