渡されたポインタが境界に揃えられていないのではないかと心配している場合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は1つではなく、x86では低速です)。
編集
スティーブジェソップのおかげで、コメントで提案された別の解決策
。一時変数のサイズを減らすことに焦点を当てています。
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;
}
少しのマイクロベンチマーク/分解が必要になる可能性があります。