这有多危险? (List <t>被强制转换为List <const t =“”>)</const> </t>

时间:2014-07-22 17:35:14

标签: c++ c++11

通常我只使用reinterpret_cast做一些低级别的事情并且#34;魔法&#34;然后我创建一个测试用例以确保它在编译时在系统上运行。

operator list<const T>&() {
    return *reinterpret_cast<list<const T>*>(this);
}

这样安全吗?这不是一个愚蠢的演员,我看不出有任何理由这是危险的,但我没有在一些非常具体的情况下使用它,我在很多地方使用列表....

所以是的,在这种特殊情况下,我没有理由认为它不安全。

该课程使用虚拟功能(所以enable_if和其他元编程不会妨碍,因为你可以混合虚拟和模板(因此SFINAE))所以我真的认为应该没问题,有人可以确认一下吗?

2 个答案:

答案 0 :(得分:6)

除非您已添加部分特化以强制list<T>list<const T>之间的继承关系,否则它们是两种完全不同的类型。标准C ++并不允许你只假装一种类型真的是另一种类型,而且由于C ++不允许它,编译器可以根据你不做的假设自由优化。当你打破这个假设时,你可以获得各种奇妙的莫名其妙的结果。

但由于这是你自己的类,你可以强制执行这样的继承关系:只需从list<T>派生list<const T>,让list<const T>完成所有工作,并list<T>提供一些额外的必要方法来修改包含的数据。

答案 1 :(得分:2)

编译器可以自由地假设这样的强制转换永远不会发生。

如果Tconst T,假设您有一些可以证明永远不会运行的代码。然后编译器可以从list<const T>中自由地消除它。如果该代码是访问private中某些bool list<const T>的唯一代码,那么编译器可以通过as-if规则自由地消除bool,作为唯一访问它的方式涉及未定义的行为(例如你的演员表等)。

这种事情会导致list<const T>的内存布局与list<T>截然不同。

您的编译器是否曾这样做过?也许不吧。您的编译器的未来版本是否会这样做?你无法分辨,因为那些未来版本尚未编写。