是否可以在标准C ++中打印变量的类型?

时间:2020-03-05 18:58:31  来源:igfitidea点击:

例如:

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

预期产量:

int

解决方案

回答

尝试:

#include <typeinfo>

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

我们可能必须在编译器选项中激活RTTI才能起作用。此外,此输出取决于编译器。它可以是原始类型名称或者名称修饰符号,或者介于两者之间的任何内容。

回答

别忘了包含&lt;typeinfo>

我相信我们所指的是运行时类型标识。我们可以通过执行以上操作。

#include <iostream>
#include <typeinfo>

using namespace std;

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

回答

我们可以为此使用traits类。就像是:

#include <iostream>
using namespace std;

template <typename T> class type_name {
public:
    static const char *name;
};

#define DECLARE_TYPE_NAME(x) template<> const char *type_name<x>::name = #x;
#define GET_TYPE_NAME(x) (type_name<typeof(x)>::name)

DECLARE_TYPE_NAME(int);

int main()
{
    int a = 12;
    cout << GET_TYPE_NAME(a) << endl;
}

存在DECLARE_TYPE_NAME定义使我们可以轻松地为所有需要的类型声明此traits类。

这可能比涉及typeid的解决方案更为有用,因为我们可以控制输出。例如,在我的编译器上将typeid用作long long会得到" x"。

回答

我们可以使用模板。

template <typename T> const char* typeof(T&) { return "unknown"; }    // default
template<> const char* typeof(int&) { return "int"; }
template<> const char* typeof(float&) { return "float"; }

在上面的示例中,当类型不匹配时,它将打印" unknown"。

回答

请注意,C ++的RTTI功能生成的名称不可移植。
例如,班级

MyNamespace::CMyContainer<int, test_MyNamespace::CMyObject>

将具有以下名称:

// MSVC 2003:
class MyNamespace::CMyContainer[int,class test_MyNamespace::CMyObject]
// G++ 4.2:
N8MyNamespace8CMyContainerIiN13test_MyNamespace9CMyObjectEEE

因此,我们不能使用此信息进行序列化。但是,仍然可以将typeid(a).name()属性用于日志/调试目的

回答

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