例如:
int a = 12;
cout << typeof(a) << endl;
Run Code Online (Sandbox Code Playgroud)
预期产量:
int
Run Code Online (Sandbox Code Playgroud) 我有一个A类和另一个继承它的类,B.我重写了一个接受A类对象作为参数的函数,所以我必须接受一个A.但是,我后来调用只有B的函数,所以我想返回false,如果传递的对象不是B类,则不继续.
找出传递给我的函数的对象的最佳方法是什么?
我目前正在研究一些日志代码,它们应该 - 除其他外 - 打印有关调用函数的信息.这应该相对容易,标准C++有一个type_info类.它包含typeid'd类/函数/ etc的名称.但它被破坏了.它不是很有用.即typeid(std::vector<int>).name()回归St6vectorIiSaIiEE.
有没有办法从中产生有用的东西?就像std::vector<int>上面的例子一样.如果它只适用于非模板类,那也没关系.
该解决方案应该适用于gcc,但如果我可以移植它会更好.这是为了记录所以它不是那么重要,它不能被关闭,但它应该有助于调试.
输出的格式type_info::name()是特定于实现的.
namespace N { struct A; }
const N::A *a;
typeid(a).name(); // returns e.g. "const struct N::A" but compiler-specific
Run Code Online (Sandbox Code Playgroud)
是否有人编写了一个包装器,它返回可靠,可预测的类型信息,这些信息在编译器中是相同的.多个模板化函数将允许用户获取有关类型的特定信息.所以我可以使用:
MyTypeInfo::name(a); // returns "const struct N::A *"
MyTypeInfo::base(a); // returns "A"
MyTypeInfo::pointer(a); // returns "*"
MyTypeInfo::nameSpace(a); // returns "N"
MyTypeInfo::cv(a); // returns "const"
Run Code Online (Sandbox Code Playgroud)
这些函数只是示例,对C++类型系统有更好了解的人可能会设计出更好的API.我感兴趣的那个base().如果禁用RTTI或检测到不支持的编译器,则所有函数都会引发异常.
这似乎是Boost可能实现的那种东西,但我无法在任何地方找到它.是否有便携式库可以做到这一点?
如果我定义了一个类:
class Blah {};
Run Code Online (Sandbox Code Playgroud)
我怎么能够:
std::string const className = /* What do I need to do here? */;
assert( className == "Blah" );
Run Code Online (Sandbox Code Playgroud)
我不认为typeid().name()是一个好主意,因为它是特定的编译器实现.有没有C++标准或Boost提供的东西?
注意:如果该类继承自Qt的QObject,我可以轻松地使用它QMetaObject::className()来获取类名.
当提供- 变量在哪里-作为参数时,我得到
PKc的输出typeid(check).name()checkchartypeid.name()
#include<bits/stdc++.h>
using namespace std;
main()
{
char check='e';
cout<<typeid(check).name()<<"\n";
cout<<typeid(typeid(check).name()).name();
}
Run Code Online (Sandbox Code Playgroud)
输出
c
PKc
Run Code Online (Sandbox Code Playgroud)
check即使将from的类型更改为 charto也能得到它double
#include<bits/stdc++.h>
using namespace std;
main()
{
double check=69.666;
cout<<typeid(check).name()<<"\n";
cout<<typeid(typeid(check).name()).name();
}
Run Code Online (Sandbox Code Playgroud)
输出
d
PKc
Run Code Online (Sandbox Code Playgroud)
PS @AsteroidsWithWings 建议的解决方案确实提供了基本概念的框架,但没有具体回答“PKc”的含义。
使用XCode 3.2.3(64位),我得到以下奇怪的输出.我究竟做错了什么?
#include <iostream>
#include <typeinfo>
struct student {
};
int main()
{
int i;
student obj;
std::cout << typeid(i).name() << "\n";
std::cout << typeid(obj).name() << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
i
7student
Run Code Online (Sandbox Code Playgroud) 我从" Inside the C++ Object Model "中读到,type_info对象通常存储在虚拟表的第一个插槽中.但是,我迭代了虚拟表中的成员:
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
typedef void(*Fun)(void);
Base b;
(Fun)*((int*)*(int*)(&b)+0); // Base::f()
(Fun)*((int*)*(int*)(&b)+1); // Base::g()
(Fun)*((int*)*(int*)(&b)+2); // Base::h()
Run Code Online (Sandbox Code Playgroud)
从最后三行看,我根本找不到type_info.
考虑以下示例:
#include <iostream>
#include <typeinfo>
int main()
{
int a=9;
std::cout << typeid(a).name() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
g ++ 4.8.1上的输出:i
MSVS 2010上的输出:int
为什么输出是编译器依赖?这背后的原因是什么?为什么它被保留为实现定义?为什么在所有编译器上没有相同的输出?C++标准是否明确地说明了这一点?
例如
callq 401400 <_ZNSaIcEC1Ev@plt>
我想知道这个函数的名称
我的编译器是 g++
考虑以下代码示例:
#include<iostream>
#include<vector>
#include<typeinfo>
int main(){
std::vector<int> v = {1 ,2,4};
for(auto &i:v) std::cout<<typeid(i).name();
for(auto k = v.begin(); k!=v.end();++k) std::cout<<typeid(k).name();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第一个循环代表基于范围的for循环,第二个循环代表带有迭代器的常规循环。我经常使用常规的,并且根据我的经验,它auto k是迭代器的类型,而基于范围的循环的类型auto i是int。上面程序的输出是:
i 和 N9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
这是基于范围的for循环的正常行为吗?因为像我这样的人会认为基于范围的for循环只是常规for循环的简写。