这个问题与这篇文章有关。
一些权威用户表示,以下代码违反了严格的别名规则。
#include <boost/static_assert.hpp>
template <typename T>
struct MyType {
private:
T data;
public:
template <typename U>
operator U () {
BOOST_STATIC_ASSERT_MSG(sizeof(U) == sizeof(T),"Trying to convert to data type of different size");
return *((U*) &data);
}
template <typename U>
NeonVectorType<T>& operator =(const U& in) {
BOOST_STATIC_ASSERT_MSG(sizeof(U) == sizeof(T),"Trying to copy from data type of different size");
data = *((T*) &in);
return *this;
}
}
然而,我从来没有使用写入数据的指针,也从来没有共享指向它的指针,所以如果编译器没有意识到这一点,我就看不到变量中包含的值是如何变化的。我的印象是,也许我违反了一些规则,但不是严格的混叠规则。。。
注意:我不知道这有多重要,但我的编译器(gcc 4.9)不会发出警告。
*((U*) &data)
如果是reinterpret_cast
并且类型U
不允许对类型T
进行别名,则会违反严格别名。允许的类型显示在此列表中。
这条规则涉及阅读和写作。
这是一篇很好的文章,解释了规则背后的一些基本原理。
正如在主要的严格混叠线程中所指出的,您可以使用memcpy
作为解决方案,例如:
U u;
memcpy( &u, &data, sizeof u );
return u;
在另一个功能中
memcpy( &data, &in, sizeof data );
请注意,类类型的原始字节副本受到一些限制(我认为类必须是POD,您最好确保它们具有相同的布局)。
然而,我从来没有使用写入数据的指针〔…〕
标准中的语言比这更通用[basic.life]/7有:
[…]一个指针指向原始对象、引用原始对象的引用或原始对象的名称对象[…]
在operator=
中,您使用类型为T
的左值写入data
,在operator U
中,使用类型为U
的指针读取它;其中CCD_ 11和CCD_。
只需使用memcpy
。它保证能工作,而且效率很高(试试)!