编译器是否消除了不必要的`dynamic_cast`?

时间:2015-11-21 19:30:27

标签: c++

我正在撰写一份沉重的模板化应用程序。在其中的某个地方,有一些类似的代码:

class TA {  };

class TX {

public:

    template <typename T>
    T &Foo(int a) {
        TA *pta;
        // here somehow initialize pta
        return *(dynamic_cast<T*>(pta));
    }

};

如果我使用Foo调用T = TA模板成员函数,动态广告dynamic_cast<TA*>(pta) [其中pta的类型为TA*]将被消除或优化编译器?或者我应该制作一些type_traits魔法来手动消除它?

1 个答案:

答案 0 :(得分:4)

是的,如果编译器可以确定转换将始终成功,那么它将省略运行时检查。在你的情况下,由于演员阵容是微不足道的,所以不能失败。

如果类型相同,则根本不进行转换。在C ++标准中,5.2.7:

  

dynamic_cast<T>(v)

     

如果v的类型与T相同,或者它与T相同,除了T中的类对象类型比v中的类对象类型更符合cv,结果是v(必要时转换) )

如果要转换为的类型是指向子类的指针或引用,则不检查运行时:

  

如果T是“指向cv1 B的指针”并且v具有类型“指向cv2 D的指针”,使得B是D的基类,则结果是指向由v指向的D对象的唯一B子对象的指针

您已编写模板而不是简单代码不会更改优化决策。您的代码与此代码相同:

struct S {};
S *foo(S *a)
{
    return dynamic_cast<S*>(a);
}

使用基本优化(g++ -O1)将以相同的方式编译为:

S *foo2(S *a)
{
    return a;
}