我想使用模板化结构来模拟 4 个维度的 double 组,每个维度的最大大小在编译时已知。因此,我认为使用模板结构将有机会获得性能。您可以在下面找到我对实现的尝试。 除非我尝试实例化一个结构,否则代码会编译。我不明白下面的代码有什么问题,将不胜感激。
更重要的是,如果可能的话,我想做两个改进:1)我希望能够使用 float 类型和 double 类型的数据 2)希望有某种重载运算符,可以将值赋给以类似于 T(N,L,M,J)=val 的方式记录数据,而不必使用 T.assign(N,L,M,J,value)。同样,我们将不胜感激。
我的目标是尽快将数据填充到 T_4D 中。
#include <iostream>
#include <cstring> // for memset
using namespace std;
template <size_t dim_N=3,size_t dim_L=3,size_t dim_M=3,size_t dim_J=10,double *data=NULL>
struct T_4D {
enum {SIZE = dim_N*dim_L*dim_M*dim_J };
enum {LEN1 = dim_N };
enum {LEN2 = dim_L };
enum {LEN3 = dim_M };
enum {LEN4 = dim_J };
static void create()
{
data=(double *)malloc(SIZE*sizeof(double));
memset(data, 0.0, SIZE*sizeof(*data));
}
static size_t multi_index(const size_t N) {
return N;
}
static size_t multi_index(const size_t N,const size_t L) {
return L*dim_N + N;
}
static size_t multi_index(const size_t N,const size_t L, const size_t M) {
return (M*dim_L + L)*dim_N + N;
}
static size_t multi_index(const size_t N,const size_t L, const size_t M,const size_t J) {
return ((J*dim_M + M)*dim_L + L)*dim_N + N;
}
double operator()(size_t N,size_t L, size_t M, size_t J){
return data[multi_index(N,L,M,J)];
}
static void assign(size_t N,size_t L, size_t M, size_t J,double value){
data[multi_index(N,L,M,J)]=value;
}
};
int main()
{
double *instance;
T_4D<3,3,3,10,instance> T;
T.create();
return 0;
}
编译错误是:
./main.cpp: In function ‘int main()’:
./main.cpp:49:17: error: the value of ‘instance’ is not usable in a constant expression
T_4D<3,3,3,10,instance> T;
^
./main.cpp:48:11: note: ‘instance’ was not declared ‘constexpr’
double *instance;
^
./main.cpp:49:25: error: ‘instance’ is not a valid template argument because ‘instance’ is a variable, not the address of a variable
T_4D<3,3,3,10,instance> T;
^
./main.cpp:50:5: error: request for member ‘create’ in ‘T’, which is of non-class type ‘int’
T.create();
^
Makefile:197: recipe for target 'obj/main.o' failed
make: *** [obj/main.o] Error 1
最佳答案
如果您的所有维度在编译时都是已知的,则无需分配动态内存。只需使用:
std::aligned_storage_t<sizeof( T ) * SIZE, alignof( T )> data;
您甚至不需要初始化任何东西,因为您正在使用 POD 类型。如果你想将内存清零,只需使用这个:
for ( std::size_t i = 0; i < SIZE; ++i )
*( reinterpret_cast<T*>( &data ) + i ) = 0;
这将是最有效的实现,因为我们使用静态连续内存。您必须实现适当的索引,但这并不难。
实际上,只需使用T data[ SIZE ];
或 std::array<T, SIZE> data
.
此外,删除 double*
模板参数,这些不能更改,因此不能用于您的数据。
关于c++ - C++ 中的高效模板结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38276344/