这有多危险?(列表<T>正在强制转换为列表<常量 T>)

How dangerous is this? (List<T> being cast to List<const T>)

本文关键字:lt gt 列表 转换 常量 危险      更新时间:2023-10-16

通常我只使用reinterpret_cast做一些低级和"神奇的"事情,然后我创建一个测试用例以确保它在编译时在系统上工作。

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

这安全吗?这不是一个愚蠢的强制转换,我不认为这有任何危险的理由,但是我不会在一些非常特殊的情况下使用它,我在很多地方使用列表....

所以,是的,我看不出在这种特殊情况下为什么不安全。

类使用虚拟函数(所以enable_if和其他元编程不能妨碍,因为你不能混合虚拟和模板(因此SFINAE)),所以我真的认为它应该是好的,有人能确认吗?

除非您添加了部分专门化来强制list<T>list<const T>之间的继承关系,否则它们是两个完全不同的类型。标准c++不允许您假装一种类型确实是另一种类型,而且由于c++不允许这样做,编译器已经根据您不这样做的假设自由地进行了优化。当你打破这个假设时,你可以得到各种奇妙的、无法解释的结果。

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

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

假设您有一些代码,可以证明如果Tconst T将永远不会运行。然后编译器可以自由地从list<const T>中删除它。如果该代码是访问list<const T>中的private bool的唯一代码,那么编译器可以根据as- If规则自由地消除该bool,因为访问它的唯一方法涉及未定义的行为(例如您的强制类型转换或类似的行为)。

这种事情可能导致list<const T>list<T>具有非常不同的内存布局。

你的编译器会这样做吗?也许不是。将来版本的编译器会这样做吗?你不能说,因为那些未来的版本还没有写出来。