問題描述
我有一個類模板 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) 類似).
An lvalue expression of type T1 can be cast to the type "reference to T2" if an expression of type "pointer to T1" can be explicitly converted to the type "pointer to T2" using a reinterpret_cast. That is, a reference cast reinterpret_cast(x) has the same effect as the conversion *reinterpret_cast(&x) with the built-in & and * operators (and similarly for 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) 更嚴格并返回到其原始類型產生原始指針值.任何其他此類指針的結果轉換未指定.
An object pointer can be explicitly converted to an object pointer of a different type. ... ... Converting a prvalue of type "pointer to T1" to the type "pointer to T2" (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.
如果 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 會導致未定義的行為嗎?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!