基于结构中的向量大小初始化数组 [c++]
Initialization of array based on vector size in structure [c++]
我正在尝试创建一个程序,将区域拆分为子集(此处为 8),每个子集包含 8 个值(对应于预定义的向量)。我定义了一个结构来存储这些值(以及向量):
struct Storage {
static const int num_spatial_subset = 8;
static const std::vector< std::vector<double> > vectors =
{ {0,0,0},
{0,1,0},
{0,0,1},
{1,1,0},
{1,0,1},
{0,1,1},
{1,0,0},
{1,1,1} };
double storage[num_spatial_subset][vectors.size()];
};
但是,我在"向量"初始化时遇到编译错误:
error: field initializer is not constant
{1,1,1} };
^
error: in-class initialization of static data member ‘const std::vector<std::vector<double> > Storage::vectors’ of non-literal type
error: non-constant in-class initialization invalid for static member ‘Storage::vectors’
error: (an out of class initialization is required)
error: ‘Storage::vectors’ cannot be initialized by a non-constant expression when being declared
error: array bound is not an integer constant before ‘]’ token
double storage[num_spatial_subset][vectors.size()];
对于所有存储对象,向量都是相同的(这就是为什么我将它们定义为静态常量)。
我知道我可以用向量替换我的存储变量并在 Storage 的构造函数中调整它的大小,但这将涉及将第一个向量的大小调整为 8,并循环将所有内部向量的大小也调整为 8。由于我可能必须创建数千个这样的对象,因此我认为这不是执行此操作的最佳方法。
我真的不明白为什么编译器抱怨,因为向量是在编译时定义的(以及向量的数量)。
谢谢。
在vector
上调用size
永远不会返回常量,因为它不符合常量C++规则。编译器不需要知道size()
做什么,并且就其所知,它返回自程序开始执行以来的时间。如果您知道该值是常量,则可以定义一个保存该值的常量。但是编译器不需要具备为您执行此操作的知识。
即使编译器确实以某种方式知道该值是恒定的,它也会通过允许您编写这样的代码来伤害您。当下一个版本的库或编译器或其他编译器不知道时会发生什么?
错误:(需要类外初始化)
所以就做
struct Storage {
static const int num_spatial_subset = 8;
static const std::vector< std::vector<double> > vectors;
double storage[num_spatial_subset][3];
};
const std::vector< std::vector<double> > Storage::vectors =
{ {0,0,0},
{0,1,0},
{0,0,1},
{1,1,0},
{1,0,1},
{0,1,1},
{1,0,0},
{1,1,1} };
作为替代方法,您可以使用initializer_list
struct Storage {
static const int num_spatial_subset = 8;
static constexpr std::initializer_list<std::initializer_list<double>> vectors{ {0,0,0},
{0,1,0},
{0,0,1},
{1,1,0},
{1,0,1},
{0,1,1},
{1,0,0},
{1,1,1} };
double storage[num_spatial_subset][vectors.size()];
};
演示
由于看起来vectors
不打算在运行时调整大小,因此我放弃了vector
并使用静态 2D 数组。
编辑:
简单的解决方案是从类中删除vectors
,以便在需要大小之前可以完全定义它。
const double vectors[][3] =
{
{ 0, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 },
{ 1, 1, 0 },
{ 1, 0, 1 },
{ 0, 1, 1 },
{ 1, 0, 0 },
{ 1, 1, 1 }
// add more here and storage will resize
};
我们无法从数组中获取数组中的行数,因此我们需要做一些工作来获取 Storage::storage
的大小。我们无法获取行,但是我们可以在编译时获取整个数组的大小(当前示例中为 sizeof(vectors)
或 8*3 *sizeof(double) = 192)和数组中行的大小(sizeof(vectors[0])
或 3 *sizeof(double) 或 24)。将总大小除以行大小将得到行数 (192/24 = 8)。
struct Storage
{
static const int num_spatial_subset = 8;
// can't get the number of rows, but we can get the total size and divide
// it by the size of a row.
double storage[num_spatial_subset][sizeof(vectors) / sizeof(vectors[0])];
};
如果向量必须包含在Storage
中,我们需要抽象以便在需要之前定义vectors
的大小:
struct BaseStorage
{
static const double vectors[][3];
};
const double BaseStorage::vectors[][3] =
{
{ 0, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 },
{ 1, 1, 0 },
{ 1, 0, 1 },
{ 0, 1, 1 },
{ 1, 0, 0 },
{ 1, 1, 1 }
// add more here and storage will resize
};
struct Storage: public BaseStorage
{
static const int num_spatial_subset = 8;
double storage[num_spatial_subset][sizeof(vectors) / sizeof(vectors[0])];
};
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在函数内部的声明中初始化数组,并在外部使用它
- 为什么用结构初始化数组需要指定结构名称
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- C++使用另一个数组和新值初始化数组
- 初始化数组、"memset"或" {//value} "的最佳方法是什么?
- 在 constexpr 构造函数中初始化数组是否合法?
- 我可以初始化 const 实例,以便我可以将其用作 const 来初始化数组吗?
- 在构造函数中初始化数组
- 是否可以使用函数返回的值初始化数组
- 使用宏使用额外元素初始化数组
- 在循环中显示不同值的初始化数组
- 如何在macOS中的旧扩展clang和gcc编译器中初始化数组和向量
- 使用可变模板列表初始化数组,并放置new
- 使用函数从 Visual Studio 2017 中的 main 创建和初始化数组
- 使用 c++ 中的函数初始化数组
- 这是使用构造函数初始化数组对象的最佳方法吗?
- C++ 使用变量而不是常量表达式初始化数组
- 在初始化列表中初始化数组的更好方法
- 在可变参数模板类中初始化数组