c++ 中的数组需要什么数据类型?
What datatype would is expected for the arrays in c++?
我一直在尝试将数据类型分配给三维数组,例如 double,但一直出现错误
error: request for member 'size' in 'msd_x', which is of non-class
type 'const sample_type' {aka 'const long unsigned int'}
-> size_t N = msd_x.size();
class mean_square_displacement
{
public:
typedef boost::multi_array_types::size_type sample_type;
//typedef fixed_vector<double, 3> result_type;
typedef double result_type;
result_type operator() (sample_type const& msd_x, sample_type const& msd_y, sample_type const& msd_z) const
{
size_t N = msd_x.size();
result_type msd = 0;
for (unsigned int i = 0; i < N; ++i) {
for (unsigned int j = 0; j < N; ++j) {
auto dr = (msd_x[i+1][j] - msd_x[i][j]) + (msd_y[i+1][j+1] - msd_y[i][j+1]) + (msd_z[i+1][j+2] - msd_z[i][j+2]);
}
// accumulate squared displacements
msd += dr * dr;
}
return msd / N;
}
}
除此之外,它还会抛出一个错误:
error: invalid types 'const sample_type {aka const long
unsigned int}[unsigned int]' for array subscript
我想代码访问数组的方式没问题。但它仍然会抛出错误。读取的数据代码为double数据类型,如下代码所示:
int main(int argc, char const* argv[])
{
correlator::multi_tau_correlator<double> corr( // TODO replace sample type
nsamples * sampling_interval / 30 trajectory length
, sampling_interval // time resolution at lowest level
, 10
);
// define time correlation functions
auto msd = make_correlation(correlator::mean_square_displacement(), corr);
corr.add_correlation(msd);
// main loop for all coordinates
for (size_t i = 1; i < nsamples; ++i) {
auto position_array = first_rows[i];
// append data to the correlator, which possibly computes some time correlations
corr.sample(position_array);
}
corr.finalise();
return 0;
}
有人指出数据类型有什么问题吗?
我是根据导致这个问题的许多问题来猜测的。
很明显,您不希望样本类型是标量,而是二维数组。
我将草拟一个通用的快捷方式,允许您编写 mean_square_displacement::operator()
来接受这些,甚至可能不知道参数的具体类型。
注意
但是,我想首先提醒您,无法知道这是否适用于您从未描述过的 multi_tau_correlator
框架。您似乎正试图以并行方式应用相关因子。
首先,correlator
框架是否允许您(技术上)这样做是未知的,其次,它可能不会很快,因为这种并行性是高度优化的库(使用实际上向量化操作,如 SIMD、AVX、OpenGL/Cuda).
我在这里看到的只是一个原始的二次循环,这对效率来说不是个好兆头。
盲目修复
因为您不希望 sample_type
成为您定义的样子,只需将它定义为其他东西,最好是您需要的东西!
typedef array_2d_t sample_type;
很有可能这不是您实际传递的内容(我怀疑是 sub_array 视图或(可选跨步)3D 多阵列的 multi_array_view 切片)。但是你可以让编译器根据你知道你可以像这样索引参数的事实来计算它 arg[int][int]
:
template <typename Sample>
result_type operator()(Sample const& msd_x, Sample const& msd_y,
Sample const& msd_z) const
这让编译器推导出具体类型,假设所有参数都具有相同的静态类型。否则,你可以更开放:
template <typename Sx, typename Sy, typename Sz>
result_type operator()(Sx const& msd_x, Sy const& msd_y,
Sz const& msd_z) const
更加谨慎
我看得出你力不从心。例如
- 在您的
mean_square_displacement
中,我们看到 auto dr
在其范围之外使用。它不会编译。对于以上内容,我已经猜到你打算将累加放入内循环。
- 您还 明确 寻址
msd_x
越界(索引 N 不存在,因为 N == msd_x.size()
)。
- 可能
msd_y
/msd_z
有相同的范围,所以他们也有这个问题,但即使 +2
- 当然,如果循环直到
N-2
的天真修复会再次冒 UB 的风险,除非您确保 N
永远不会 <2
以下是使此代码看起来在技术上可行的最少修复:
struct mean_square_displacement {
//typedef fixed_vector<double, 3> result_type;
typedef double result_type;
template <typename Sample>
result_type operator()(Sample const& msd_x, Sample const& msd_y,
Sample const& msd_z) const
{
size_t N = msd_x.size();
assert(N>=2);
result_type msd = 0;
for (unsigned int i = 0; i < N-1; ++i) {
for (unsigned int j = 0; j < N-2; ++j) {
auto dr = //
(msd_x[i + 1][j + 0] - msd_x[i][j + 0]) +
(msd_y[i + 1][j + 1] - msd_y[i][j + 1]) +
(msd_z[i + 1][j + 2] - msd_z[i][j + 2]);
// accumulate squared displacements
msd += dr * dr;
}
}
return msd / N;
}
};
我一直在尝试将数据类型分配给三维数组,例如 double,但一直出现错误
error: request for member 'size' in 'msd_x', which is of non-class
type 'const sample_type' {aka 'const long unsigned int'}
-> size_t N = msd_x.size();
class mean_square_displacement
{
public:
typedef boost::multi_array_types::size_type sample_type;
//typedef fixed_vector<double, 3> result_type;
typedef double result_type;
result_type operator() (sample_type const& msd_x, sample_type const& msd_y, sample_type const& msd_z) const
{
size_t N = msd_x.size();
result_type msd = 0;
for (unsigned int i = 0; i < N; ++i) {
for (unsigned int j = 0; j < N; ++j) {
auto dr = (msd_x[i+1][j] - msd_x[i][j]) + (msd_y[i+1][j+1] - msd_y[i][j+1]) + (msd_z[i+1][j+2] - msd_z[i][j+2]);
}
// accumulate squared displacements
msd += dr * dr;
}
return msd / N;
}
}
除此之外,它还会抛出一个错误:
error: invalid types 'const sample_type {aka const long
unsigned int}[unsigned int]' for array subscript
我想代码访问数组的方式没问题。但它仍然会抛出错误。读取的数据代码为double数据类型,如下代码所示:
int main(int argc, char const* argv[])
{
correlator::multi_tau_correlator<double> corr( // TODO replace sample type
nsamples * sampling_interval / 30 trajectory length
, sampling_interval // time resolution at lowest level
, 10
);
// define time correlation functions
auto msd = make_correlation(correlator::mean_square_displacement(), corr);
corr.add_correlation(msd);
// main loop for all coordinates
for (size_t i = 1; i < nsamples; ++i) {
auto position_array = first_rows[i];
// append data to the correlator, which possibly computes some time correlations
corr.sample(position_array);
}
corr.finalise();
return 0;
}
有人指出数据类型有什么问题吗?
我是根据导致这个问题的许多问题来猜测的。
很明显,您不希望样本类型是标量,而是二维数组。
我将草拟一个通用的快捷方式,允许您编写 mean_square_displacement::operator()
来接受这些,甚至可能不知道参数的具体类型。
注意
但是,我想首先提醒您,无法知道这是否适用于您从未描述过的 multi_tau_correlator
框架。您似乎正试图以并行方式应用相关因子。
首先,correlator
框架是否允许您(技术上)这样做是未知的,其次,它可能不会很快,因为这种并行性是高度优化的库(使用实际上向量化操作,如 SIMD、AVX、OpenGL/Cuda).
我在这里看到的只是一个原始的二次循环,这对效率来说不是个好兆头。
盲目修复
因为您不希望 sample_type
成为您定义的样子,只需将它定义为其他东西,最好是您需要的东西!
typedef array_2d_t sample_type;
很有可能这不是您实际传递的内容(我怀疑是 sub_array 视图或(可选跨步)3D 多阵列的 multi_array_view 切片)。但是你可以让编译器根据你知道你可以像这样索引参数的事实来计算它 arg[int][int]
:
template <typename Sample>
result_type operator()(Sample const& msd_x, Sample const& msd_y,
Sample const& msd_z) const
这让编译器推导出具体类型,假设所有参数都具有相同的静态类型。否则,你可以更开放:
template <typename Sx, typename Sy, typename Sz>
result_type operator()(Sx const& msd_x, Sy const& msd_y,
Sz const& msd_z) const
更加谨慎
我看得出你力不从心。例如
- 在您的
mean_square_displacement
中,我们看到auto dr
在其范围之外使用。它不会编译。对于以上内容,我已经猜到你打算将累加放入内循环。 - 您还 明确 寻址
msd_x
越界(索引 N 不存在,因为N == msd_x.size()
)。 - 可能
msd_y
/msd_z
有相同的范围,所以他们也有这个问题,但即使 +2 - 当然,如果循环直到
N-2
的天真修复会再次冒 UB 的风险,除非您确保N
永远不会 <2
以下是使此代码看起来在技术上可行的最少修复:
struct mean_square_displacement {
//typedef fixed_vector<double, 3> result_type;
typedef double result_type;
template <typename Sample>
result_type operator()(Sample const& msd_x, Sample const& msd_y,
Sample const& msd_z) const
{
size_t N = msd_x.size();
assert(N>=2);
result_type msd = 0;
for (unsigned int i = 0; i < N-1; ++i) {
for (unsigned int j = 0; j < N-2; ++j) {
auto dr = //
(msd_x[i + 1][j + 0] - msd_x[i][j + 0]) +
(msd_y[i + 1][j + 1] - msd_y[i][j + 1]) +
(msd_z[i + 1][j + 2] - msd_z[i][j + 2]);
// accumulate squared displacements
msd += dr * dr;
}
}
return msd / N;
}
};