正在投射 std::pair<T1, T2>;常量&到 std::pair<T1 const, T2>常量&安全的?
reinterpret_cast
std::pair
变成 std::pair
,假设程序员没有故意做一些奇怪的事情,比如专门化 std::pair<T1 const, T2>
?
Is it safe (in theory or in practice) to reinterpret_cast
a std::pair<T1, T2> const &
into a std::pair<T1 const, T2> const &
, assuming that the programmer hasn't intentionally done something weird like specializing std::pair<T1 const, T2>
?
推荐答案
这样做是不可移植的.
std::pair
要求在第 20.3 节中列出.第 17.5.2.3 条阐明了
std::pair
requirements are laid out in clause 20.3. Clause 17.5.2.3 clarifies that
第 18 到 30 条和附录 D 没有指定类的表示,并且有意省略了类成员的说明.实现可以根据需要定义静态或非静态类成员,或两者兼而有之,以实现第 18 条至第 30 条和附录 D 中指定的成员函数的语义.
Clauses 18 through 30 and Annex D do not specify the representation of classes, and intentionally omit specification of class members. An implementation may define static or non-static class members, or both, as needed to implement the semantics of the member functions specified in Clauses 18 through 30 and Annex D.
这意味着实现包含部分特化是合法的(尽管极不可能),例如:
This implies that it's legal (although incredibly unlikely) for an implementation to include a partial specialization such as:
template<typename T1, typename T2>
struct pair<T1, T2>
{
T1 first;
T2 second;
};
template<typename T1, typename T2>
struct pair<const T1, T2>
{
T2 second;
const T1 first;
};
显然不兼容布局.该规则还允许其他变体,包括可能在 first
和/或 second
之前包含额外的非静态数据成员.
which are clearly not layout-compatible. Other variations including inclusion of additional non-static data members possibly before first
and/or second
are also allowed under the rule.
现在,考虑一下布局已知的情况有点有趣.尽管 Potatoswatter 指出 DR1334 断言 T
和 const T
不是 layout-compatible,标准提供了足够的保证让我们无论如何都能获得大部分的方式:
Now, it is somewhat interesting to consider the case where the layout is known. Although Potatoswatter pointed out DR1334 which asserts that T
and const T
are not layout-compatible, the Standard provides enough guarantees to allow us to get most of the way anyway:
template<typename T1, typename T2>
struct mypair<T1, T2>
{
T1 first;
T2 second;
};
mypair<int, double> pair1;
mypair<int, double>* p1 = &pair1;
int* p2 = reinterpret_cast<int*>(p1); // legal by 9.2p20
const int* p3 = p2;
mypair<const int, double>* p4 = reinterpret_cast<mypair<const int, double>*>(p3); // again 9.2p20
但是,这在 std::pair
上不起作用,因为我们无法在不知道 first
实际上是初始成员的情况下应用 9.2p20,但未指定.
However this doesn't work on std::pair
as we can't apply 9.2p20 without knowing that first
is actually the initial member, which is not specified.
相关文章