静态断言,基指针"等于"派生指针

时间:2015-08-07 12:42:28

标签: c++ inheritance static-assert

假设我有一个具有共同基础的类的多态层次结构:

struct Base { ~virtual Base() = default; };

我继承了一个包含一系列访问函数(每个派生类型一个)的大型代码库,它通过reinterpret_cast获取派生指针:

Derived * Get()       // Derived inherits from Base
{
    Base * b = lookup_derived();
    return reinterpret_cast<Derived *>(b);
}

显然代码应该使用static_castdynamic_cast(取决于基数是否为虚拟)。但是,由于此转换单元很大且所有派生类的定义都很大,因此TU不包含Derived的定义,而只包含其声明。

我想通过向每个派生类定义添加一个静态断言来使这段代码更加健壮,这种重新解释强制转换将产生正确的结果。基本上,我想要这样的东西:

struct Derived : Base
{
    static_assert(static_cast<Derived *>(std::declval<Base *>()) ==
                  reinterpret_cast<Derived *>(std::declval<Base *>()));

    // ...
};

这个结构当然不起作用,因为不能评估declval,并且重新解释转换的结果不是常量表达式。有静态执行此类测试的标准C ++机制吗? (替代方法是在类构造函数中对this进行运行时检查。)

编辑:根据Aaron的帖子,我突然想到这个问题可以在没有reinterpret_casts的情况下完全表达:

static_cast<void *>(std::declval<Derived *>()) ==
static_cast<void *>(static_cast<Base *>(std::declval<Derived *>()))

1 个答案:

答案 0 :(得分:2)

我不确定这对你的设置是否足够好,但是this code on ideone对我有用(clang 3.5.0和g ++ 4.9.3)。

更新为向另一个方向投射,即e。 Base* - 至 - static_cast<void*>,以更接近地匹配问题。并且还更新为明确使用reinterpret_cast而不是C风格的投射和template<typename D, typename B> struct CheckCasting { static D d_static; constexpr static B* bp = &d_static; // the original object is D, // that allows us to static_cast both ways static constexpr bool static_equals_reinterpret() { return static_cast<void*>(static_cast<D*>(bp)) == static_cast<void*>( bp ); } }; struct Base { constexpr Base() : i(0) {} int i; }; struct derived_with_virtual : public Base { derived_with_virtual() {} virtual void foo() { } }; struct without_virtual : public Base { without_virtual() {} }; static_assert( ! CheckCasting<derived_with_virtual, Base> :: static_equals_reinterpret() ,""); static_assert( CheckCasting<without_virtual , Base> :: static_equals_reinterpret() ,"");

void*

一些评论:

  • 我尝试用reinterpret_cast将转换替换为static_assert,但clang并不喜欢这样。 &#34;注意:在常量表达式中不允许使用reinterpret_cast&#34;。
  • 我尝试在Derived类中移动<script type="text/ng-template" id="weekCarouselTemplate"> <br> <br> <br> <br> <div id="weekCarousel_{{$index}}" class="carousel slide"> <a href="#weekCarousel_{{$index}}" data-slide="prev" class="prevweek"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> </a> <div class="carousel-inner"> <div class="item" ng-repeat="week in ls_weeks" data-slide-number="{{$index}}" ng-class="makeActive(week)"> <div class="weekList"> <div style="float:left"; ng-class="highlightDay($index,week,usrLifestyle.lsid)" ng-repeat="d in ls_days track by $index" ng-click='weekdayClicked($index,week,usrLifestyle.lsName,usrLifestyle.lsid,usrLifestyle.insertTimestmp)'> {{d}} </div> </div> </div> </div> <a href="#weekCarousel_{{$index}}" data-slide="next" class="nextweek"> <div class="glyphicon glyphicon-chevron-right" aria-hidden="true"></div> </a> </div> <br> <br> </script> 但没有成功。
  • 这需要为每个Derived类静态分配一个对象。