请注意,如果typeid运算符是具有虚拟成员的类型的左值,则它将在运行时计算。
我有一个简单的Base
课程如下
class Base
{
public:
Base(const std::string &s):sval(s){}
virtual ~Base()=default;
private:
std::string sval;
};
和一个简单的函数来返回Base的左值,如下所示:
Base& ChangeBase(Base &b)
{
std::cout<<"Called"<<std::endl;
return b;
}
当我编写以下代码来检查typeid运算符时:
int main()
{
Base b("Dream");
typeid (ChangeBase(b));
return 0;
}
我得到了以下输出:
Called
Called
它表示函数ChangeBase
被调用了两次,所以它是否意味着在运行时将对typeid中的表达式求值两次(如果需要在运行时进行求值)?如果是,为什么?
我正在使用gcc 4.9.3
答案 0 :(得分:2)
GCC首先检查值是否为null,然后再次对其进行评估,并且仅在调用后才调用typeid。
大会:https://godbolt.org/g/SoLFYq
lea rax, [rbp-64]
mov rdi, rax
call ChangeBase(Base&)
test rax, rax
je .L8
lea rax, [rbp-64]
mov rdi, rax
call ChangeBase(Base&)
...
.L8:
call __cxa_bad_typeid