是否可以安全地转换为具有相同数据成员布局但具有不同实现的类? [英] Is it safe to cast to a class that has the same data member layout, but a different implementation?
问题描述
第一个类将用于私有继承,以确保完全相同的布局。这将使投射更安全。
The first class will be used for private inheritance in order to ensure the exact same layout. This should make casting safe.
#include <iostream>
#include <string>
struct data_base
{
data_base( int i, std::string&& s ) noexcept
: i_{ i }
, s_{ std::move( s ) }
{}
int i_;
std::string s_;
};
在这个简单的例子中,我打印 int
数据成员,随后是 data
实例的 std :: string
数据成员。 >
In this trivial example, I print the int
data member first followed by the std::string
data member for instances of data<true>
.
template<bool = true>
struct data : private data_base // inherits
{
data( int i, std::string&& s ) noexcept
: data_base( i, std::move( s ) )
{}
void print()
{
std::cout << "data<true> - " << i_ << s_ << '\n';
}
};
但是, data< false>
std :: string
数据成员,随后是 int
数据成员。
However, the data<false>
prints the std::string
data member first, followed by the int
data member.
template<>
struct data<false> : private data_base
{
void print()
{
std::cout << "data<false> - " << s_ << i_ << '\n';
}
};
示例:
int main()
{
data<true> d{ 5, "abc" };
d.print();
( ( data<false>& )d ).print();
}
演示: http://coliru.stacked-crooked.com/a/8b1262afe23dc0a2
演示显示,即使使用 -fstrict-aliasing
标志,没有警告。
As the demo shows, even with the -fstrict-aliasing
flag on, there's no warnings.
现在,由于他们有相同的布局,我可以在两种类型之间转换,以获得一种不同类型的静态多态性;
Now, since they have the same layout, I thought that I could just cast between the two types in order to get a different kind of static polymorphism; without the cost of a virtual function call.
此使用是否安全或是否触发未定义的行为?
推荐答案
它或多或少描述了这里,所谓的 boost突变成语
It's more or less what's described here, the so called boost mutant idiom.
:
Boost突变成语使用
reinterpret_cast
,并且在很大程度上取决于具有相同数据成员(类型和顺序)的两个不同结构的存储器布局是可互换的。 虽然C ++标准不保证此属性,但实际上所有编译器都满足。此外,如果仅使用POD类型,则突变成语是标准的。
Boost mutant idiom makes use of
reinterpret_cast
and depends heavily on assumption that the memory layouts of two different structures with identical data members (types and order) are interchangeable. Although the C++ standard does not guarantee this property, virtually all the compilers satisfy it. Moreover, the mutant idiom is standard if only POD types are used.
注意:该页面已过时,我不知道最近的修订版是否改变了上述保证金。
Note: that page is pretty outdated, I don't know if the most recent revisions changed something about the guarantees above mentioned.
这篇关于是否可以安全地转换为具有相同数据成员布局但具有不同实现的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!