问题描述
我有一个类模板 A
,它包含一个指针容器 (T*
):
I have a class template A
which contains a container of pointers (T*
):
template <typename T>
class A {
public:
// ...
private:
std::vector<T*> data;
};
还有一堆函数,比如:
void f(const A<const T>&);
void g(const A<const T>&);
是否可以通过从 A
到 A
的强制转换来调用这些函数?
Is it OK to call these functions via a cast from A<const T>
to A<T>
?
A<double> a;
...
auto& ac = reinterpret_cast<const A<const double>&>(a);
f(ac);
我很确定这段代码有未定义的行为.
I'm pretty sure that this code has undefined behaviour.
在现实生活中使用此类转换是否危险?
Is it dangerous to use such conversions in real life?
推荐答案
由于 A
和 A
是不相关的类型,它实际上是未指定的(最初我认为未定义的)行为,相应地,在现实生活中使用它是一个坏主意:你永远不知道你可以移植什么系统或编译器来改变行为是奇怪的方式.
As A<double>
and A<const double>
are unrelated types, it's actually unspecified (originally I thought undefined) behavior and correspondingly yes it's a bad idea to use in real life: You never know what system(s) or compiler(s) you may port to that change the behavior is strange ways.
参考:
5.2.10/11:
T1 类型的左值表达式可以转换为引用到T2",如果指向 T1 的指针"类型的表达式可以显式表示使用 reinterpret_cast 转换为指向 T2 的指针"类型.那即,参考强制转换 reinterpret_cast(x) 具有相同的效果使用内置的 & 转换 *reinterpret_cast(&x)和 *运算符(与 reinterpret_cast(x) 类似).
所以他们将我们重定向到了之前的 5.2.10/7 部分:
So they've redirected us to an earlier section 5.2.10/7:
对象指针可以显式转换为一种不同的类型.... ... 转换类型的纯右值指向 T1 的指针"指向指向 T2 的指针"类型(其中 T1 和 T2 是对象类型和 T2 的对齐要求没有的地方比 T1) 更严格并返回到其原始类型产生原始指针值.任何其他此类指针的结果转换未指定.
如果 f
和 g
是适用于容器的算法,那么简单的解决方案是将它们更改为适用于范围(迭代器对)的模板算法.
If f
and g
are algorithms that work on containers, the easy solution is to change them to template algorithms that work on ranges (iterator pairs).
这篇关于reinterpret_cast 会导致未定义的行为吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!