我想知道是否有必要在下面的函数中重新解释。 ITER_T可能是char *,unsigned char *,std :: vector< unsigned char>迭代器,或其他类似的东西。到目前为止它似乎没有受到伤害,但是转换是否会影响字节的复制方式?
template<class ITER_T>
char *copy_binary(
unsigned char length,
const ITER_T& begin)
{
// alloc_storage() returns a char*
unsigned char* stg = reinterpret_cast<unsigned char*>(alloc_storage(length));
std::copy(begin, begin + length, stg);
return reinterpret_cast<char*>(stg);
}
答案 0 :(得分:6)
reinterpret_casts
用于低级实现定义的强制转换。根据标准,reinterpret_casts
可用于以下转换(C ++ 03 5.2.10):
reinterpret_cast
将指向类型A的指针显式转换为类型B,则可以将类型A的表达式转换为对类型B的引用。也就是说,在你的情况下使用reinterpret_cast
不是一个好的解决方案,因为标准没有指定转换为不同的类型,但是从char *
转换为unsigned char *
并返回在大多数机器上工作。
在您的情况下,我会考虑将static_cast
定义为stg
类型为char *
,而不是使用template<class ITER_T>
char *copy_binary(
unsigned char length,
const ITER_T& begin)
{
// alloc_storage() returns a char*
char* stg = alloc_storage(length);
std::copy(begin, begin + length, stg);
return stg;
}
:
{{1}}
答案 1 :(得分:1)
根据标准4.7(2),编写的代码按预期工作,但这仅适用于具有二进制补码表示的机器。
如果alloc_storage返回一个char *,并且'char'被签名,那么如果我正确理解了4.7(3),那么如果迭代器的值类型是unsigned并且你放弃了强制转换并传递了char,那么结果将是实现定义的*复制。
答案 2 :(得分:1)
简短的回答是肯定的,它可能会影响。
char 和 unsigned char 是可转换类型(C ++标准0x n2800中的3.9.1),因此您可以将一个分配给另一个。 您根本不需要演员。
[3.9.1] ...一个字母,一个签名的字符和一个未签名的字符 char占用相同的存储空间 并具有相同的对齐方式 要求;也就是说,他们有 相同的对象表示 。
[4.7] ......
2 如果目的地类型是 无符号,结果值是 最小符号无符号整数 源整数(模2n,其中n 是用于的位数 代表无符号类型)。
[注意: 在二进制补码表示中, 这种转换是概念性的 位模式没有变化 (如果没有截断)。 - 注意 ]
3 如果目标类型已签名, 值不变 如果可以的话 以目的地类型表示 (和位域宽度);否则, 值是实现定义的。
因此,即使在最坏的情况下,您也会获得最佳(实现定义较少)的转换。无论如何,在大多数实现中,这不会改变位模式中的任何内容,如果查看生成的汇编程序,您甚至不会进行转换。
template<class ITER_T>
char *copy_binary( unsigned char length, const ITER_T& begin)
{
char* stg = alloc_storage(length);
std::copy(begin, begin + length, stg);
return stg;
}
使用reinterpret_cast,你依赖于编译器:
[5.2.10.3]执行的映射 reinterpret_cast是 的 实现定义 即可。 [注意:它 可能会,也可能不会产生 表示不同于 原始价值。 - 后注]
注意:This是一个有趣的相关帖子。
答案 3 :(得分:0)
因此,如果我做对了,对无符号字符的强制转换是为了保证一个无符号的逐字节拷贝。但是你把它归还给了回归。该函数看起来有点狡猾,这样设置的上下文/原因究竟是什么?快速修复可能是用memcpy()替换所有这些(但是注释,不要在迭代器对象上使用它) - 否则只需删除多余的强制转换。