例如:

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

其他回答

对于那些还在访问的人,我最近也遇到了同样的问题,并决定根据这篇文章的答案编写一个小型库。它提供了constexpr类型名称和类型索引,并且在Mac, Windows和Ubuntu上进行了测试。

库代码在这里:https://github.com/TheLartians/StaticTypeInfo

根据Howard的解决方案,如果你不喜欢神奇的数字,我认为这是一种很好的表示方式,看起来很直观:

#include <string_view>

template <typename T>
constexpr auto type_name() {
  std::string_view name, prefix, suffix;
#ifdef __clang__
  name = __PRETTY_FUNCTION__;
  prefix = "auto type_name() [T = ";
  suffix = "]";
#elif defined(__GNUC__)
  name = __PRETTY_FUNCTION__;
  prefix = "constexpr auto type_name() [with T = ";
  suffix = "]";
#elif defined(_MSC_VER)
  name = __FUNCSIG__;
  prefix = "auto __cdecl type_name<";
  suffix = ">(void)";
#endif
  name.remove_prefix(prefix.size());
  name.remove_suffix(suffix.size());
  return name;
}

演示。

#include <iostream>
#include <typeinfo>
using namespace std;
#define show_type_name(_t) \
    system(("echo " + string(typeid(_t).name()) + " | c++filt -t").c_str())

int main() {
    auto a = {"one", "two", "three"};
    cout << "Type of a: " << typeid(a).name() << endl;
    cout << "Real type of a:\n";
    show_type_name(a);
    for (auto s : a) {
        if (string(s) == "one") {
            cout << "Type of s: " << typeid(s).name() << endl;
            cout << "Real type of s:\n";
            show_type_name(s);
        }
        cout << s << endl;
    }

    int i = 5;
    cout << "Type of i: " << typeid(i).name() << endl;
    cout << "Real type of i:\n";
    show_type_name(i);
    return 0;
}

输出:

Type of a: St16initializer_listIPKcE
Real type of a:
std::initializer_list<char const*>
Type of s: PKc
Real type of s:
char const*
one
two
three
Type of i: i
Real type of i:
int

如前所述,typeid().name()可能返回一个错误的名称。在GCC(和其他一些编译器)中,你可以使用以下代码来解决它:

#include <cxxabi.h>
#include <iostream>
#include <typeinfo>
#include <cstdlib>

namespace some_namespace { namespace another_namespace {

  class my_class { };

} }

int main() {
  typedef some_namespace::another_namespace::my_class my_type;
  // mangled
  std::cout << typeid(my_type).name() << std::endl;

  // unmangled
  int status = 0;
  char* demangled = abi::__cxa_demangle(typeid(my_type).name(), 0, 0, &status);

  switch (status) {
    case -1: {
      // could not allocate memory
      std::cout << "Could not allocate memory" << std::endl;
      return -1;
    } break;
    case -2: {
      // invalid name under the C++ ABI mangling rules
      std::cout << "Invalid name" << std::endl;
      return -1;
    } break;
    case -3: {
      // invalid argument
      std::cout << "Invalid argument to demangle()" << std::endl;
      return -1;
    } break;
 }
 std::cout << demangled << std::endl;

 free(demangled);

 return 0;

}

Try:

#include <typeinfo>

// …
std::cout << typeid(a).name() << '\n';

您可能必须在编译器选项中激活RTTI才能使其工作。此外,它的输出取决于编译器。它可能是一个原始类型名称或名称混乱符号或介于两者之间的任何东西。