如果您担心传递的指针未与float
边界对齐(例如,文件映射等),那么您可以编写类似
template<std::size_t dim>
class Foo {
public:
Foo(void const * const data)
{
float temp[dim];
memcpy( &temp, data, dim * sizeof( float ) );
std::copy( temp, temp + dim, vals );
}
private:
double vals[dim];
}
可能是一个过分热心且不太便携的解决方案:
template<std::size_t dim>
class Foo {
public:
Foo(void const * const data)
{
if( static_cast<long>( data ) % sizeof( float ) == 0 ) {
const float *temp = data;
std::copy( temp, temp + dim, vals );
} else {
float temp[dim];
memcpy( &temp, data, dim * sizeof( float ) );
std::copy( temp, temp + dim, vals );
}
}
private:
double vals[dim];
}
在初始化器列表中初始化不会使您的代码更快,它只是在可能的情况下提供便利。
如果您非常关心性能,我会将其包装if
在一个宏中,并且仅if
在需要正确对齐访问的架构上使用(x86 不是一个,它只是在 x86 上速度较慢)。
编辑
感谢
Steve Jessop在评论中提出的另一个解决方案。它侧重于减少临时变量的大小。
double *dest = vals;
float tmp;
void const *first = data;
void const *last = data + dim * sizeof(float);
while( first != last ) {
memcpy( &tmp, first, sizeof(float) );
first += sizeof(float);
*dest++ = tmp;
}
可能需要进行一些微基准测试/分解。