将初始化列表传递给 C++ 中的数组成员
Passing an initialization list to an array member in C++
使用聚合 class 时,传入数组成员的初始化列表不是问题。例如:
class color_def
{
public:
const u8 color_passes;
const u8 red_shift[MAX_COLOR_PASSES];
const u8 red_bitcount[MAX_COLOR_PASSES];
const u8 green_shift[MAX_COLOR_PASSES];
const u8 green_bitcount[MAX_COLOR_PASSES];
const u8 blue_shift[MAX_COLOR_PASSES];
const u8 blue_bitcount[MAX_COLOR_PASSES];
};
const static color_def snk_neogeo_color = {
3, {15, 14, 8}, {1, 1, 4}, {15, 13, 4}, {1, 1, 4}, {15, 12, 0}, {1, 1, 4}};
这没有任何问题。但是,当我添加一个显式构造函数时,它将不起作用。例如,来自类似 class:
class chr_def
{
public:
chr_def(u16 width, u16 height, u8 bitplanes, u32 planeoffset[MAX_GFX_PLANES],
u32 xoffset[MAX_GFX_SIZE], u32 yoffset[MAX_GFX_SIZE],
const u8 *(*converter)(const chr_def *chrdef, const u8 *data))
: width(width),
height(height),
bitplanes(bitplanes),
planeoffset{planeoffset},
xoffset(xoffset),
yoffset(yoffset),
converter(converter),
datasize(width * height * bitplanes){};
const u8 *convert(const u8 *data) { return this->converter(this, data); }
const u16 width; // pixel width of each element
const u16 height; // pixel height of each element
const u8 bitplanes; // number of color bitplanes
const u32 *planeoffset; // bit offset of each bitplane
const u32 *xoffset; // bit offset of each horizontal pixel
const u32 *yoffset; // bit offset of each vertical pixel
const u32 datasize; // size of one chr in bits
const u8 *(*converter)(const chr_def *, const u8 *);
};
const static chr_def nintendo_sfc = {
8,
8,
4,
{0, 8, 128, 136},
{0, 1, 2, 3, 4, 5, 6, 7},
{0 * 16, 1 * 16, 2 * 16, 3 * 16, 4 * 16, 5 * 16, 6 * 16, 7 * 16},
get_chr};
失败,抱怨参数与构造函数不匹配。问题似乎是它将数组初始化列表的第一个值作为指向数组的指针:
note: candidate constructor not viable: cannot convert initializer list argument to 'u32 *' (aka 'unsigned int *')
如果我拉出数组初始化列表并预先将它们初始化为自己的变量,如下所示:
u32 temp1[4] = {0, 8, 128, 136};
u32 temp2[8] = {0, 1, 2, 3, 4, 5, 6, 7};
u32 temp3[8] = {0 * 16, 1 * 16, 2 * 16, 3 * 16, 4 * 16, 5 * 16, 6 * 16, 7 * 16};
const static chr_def nintendo_sfc = {
8,
8,
4,
temp1,
temp2,
temp3,
get_chr};
一切正常。如果可能的话,我真的更喜欢 而不是 这样做。
那么...为什么这在聚合形式中有效,但在我的显式构造函数中却无效?有什么方法可以使这项工作吗?感谢任何人提供的任何见解。
给您带来麻烦的不是显式构造函数,而是您使用的指针而不是数组:
以下变量声明:
const u8 red_shift[MAX_COLOR_PASSES];
const u8 red_bitcount[MAX_COLOR_PASSES];
const u8 green_shift[MAX_COLOR_PASSES];
const u8 green_bitcount[MAX_COLOR_PASSES];
const u8 blue_shift[MAX_COLOR_PASSES];
const u8 blue_bitcount[MAX_COLOR_PASSES];
成为:
const u32 *planeoffset; // bit offset of each bitplane
const u32 *xoffset; // bit offset of each horizontal pixel
const u32 *yoffset; // bit offset of each vertical pixel
指针与数组不同。
您可以阅读它们之间的区别:Is an array name a pointer?
要启用这些指针,您必须在构造函数中接收接受 initializer_list 的类型,然后在函数内部您必须为指针分配内存中的新位置,然后从数组中复制值到你新分配的指针。
您遇到的问题是您试图用 std::initializer_list
初始化指针成员,这是不可能的。
但是,您可以使用 std::array
(自 c++ 11 起)。这是一个简化的例子:
#include <iostream>
#include <array>
#define MAX_GFX_PLANES (4U)
struct chr_def {
// Constructor
chr_def(size_t size, const std::array<unsigned int, MAX_GFX_PLANES>& planeoffset) :
size(size), planeoffset(planeoffset) { };
// Data Members
const size_t size;
const std::array<unsigned int, MAX_GFX_PLANES> planeoffset;
};
const static chr_def nintendo_sfc{ 8U, {0U, 1U, 2U, 3U} };
int main() {
// std::array can be used with range-based for
for (auto i : nintendo_sfc.planeoffset) {
std::cout << i << " ";
}
return 0;
}
使用聚合 class 时,传入数组成员的初始化列表不是问题。例如:
class color_def
{
public:
const u8 color_passes;
const u8 red_shift[MAX_COLOR_PASSES];
const u8 red_bitcount[MAX_COLOR_PASSES];
const u8 green_shift[MAX_COLOR_PASSES];
const u8 green_bitcount[MAX_COLOR_PASSES];
const u8 blue_shift[MAX_COLOR_PASSES];
const u8 blue_bitcount[MAX_COLOR_PASSES];
};
const static color_def snk_neogeo_color = {
3, {15, 14, 8}, {1, 1, 4}, {15, 13, 4}, {1, 1, 4}, {15, 12, 0}, {1, 1, 4}};
这没有任何问题。但是,当我添加一个显式构造函数时,它将不起作用。例如,来自类似 class:
class chr_def
{
public:
chr_def(u16 width, u16 height, u8 bitplanes, u32 planeoffset[MAX_GFX_PLANES],
u32 xoffset[MAX_GFX_SIZE], u32 yoffset[MAX_GFX_SIZE],
const u8 *(*converter)(const chr_def *chrdef, const u8 *data))
: width(width),
height(height),
bitplanes(bitplanes),
planeoffset{planeoffset},
xoffset(xoffset),
yoffset(yoffset),
converter(converter),
datasize(width * height * bitplanes){};
const u8 *convert(const u8 *data) { return this->converter(this, data); }
const u16 width; // pixel width of each element
const u16 height; // pixel height of each element
const u8 bitplanes; // number of color bitplanes
const u32 *planeoffset; // bit offset of each bitplane
const u32 *xoffset; // bit offset of each horizontal pixel
const u32 *yoffset; // bit offset of each vertical pixel
const u32 datasize; // size of one chr in bits
const u8 *(*converter)(const chr_def *, const u8 *);
};
const static chr_def nintendo_sfc = {
8,
8,
4,
{0, 8, 128, 136},
{0, 1, 2, 3, 4, 5, 6, 7},
{0 * 16, 1 * 16, 2 * 16, 3 * 16, 4 * 16, 5 * 16, 6 * 16, 7 * 16},
get_chr};
失败,抱怨参数与构造函数不匹配。问题似乎是它将数组初始化列表的第一个值作为指向数组的指针:
note: candidate constructor not viable: cannot convert initializer list argument to 'u32 *' (aka 'unsigned int *')
如果我拉出数组初始化列表并预先将它们初始化为自己的变量,如下所示:
u32 temp1[4] = {0, 8, 128, 136};
u32 temp2[8] = {0, 1, 2, 3, 4, 5, 6, 7};
u32 temp3[8] = {0 * 16, 1 * 16, 2 * 16, 3 * 16, 4 * 16, 5 * 16, 6 * 16, 7 * 16};
const static chr_def nintendo_sfc = {
8,
8,
4,
temp1,
temp2,
temp3,
get_chr};
一切正常。如果可能的话,我真的更喜欢 而不是 这样做。
那么...为什么这在聚合形式中有效,但在我的显式构造函数中却无效?有什么方法可以使这项工作吗?感谢任何人提供的任何见解。
给您带来麻烦的不是显式构造函数,而是您使用的指针而不是数组:
以下变量声明:
const u8 red_shift[MAX_COLOR_PASSES];
const u8 red_bitcount[MAX_COLOR_PASSES];
const u8 green_shift[MAX_COLOR_PASSES];
const u8 green_bitcount[MAX_COLOR_PASSES];
const u8 blue_shift[MAX_COLOR_PASSES];
const u8 blue_bitcount[MAX_COLOR_PASSES];
成为:
const u32 *planeoffset; // bit offset of each bitplane
const u32 *xoffset; // bit offset of each horizontal pixel
const u32 *yoffset; // bit offset of each vertical pixel
指针与数组不同。
您可以阅读它们之间的区别:Is an array name a pointer?
要启用这些指针,您必须在构造函数中接收接受 initializer_list 的类型,然后在函数内部您必须为指针分配内存中的新位置,然后从数组中复制值到你新分配的指针。
您遇到的问题是您试图用 std::initializer_list
初始化指针成员,这是不可能的。
但是,您可以使用 std::array
(自 c++ 11 起)。这是一个简化的例子:
#include <iostream>
#include <array>
#define MAX_GFX_PLANES (4U)
struct chr_def {
// Constructor
chr_def(size_t size, const std::array<unsigned int, MAX_GFX_PLANES>& planeoffset) :
size(size), planeoffset(planeoffset) { };
// Data Members
const size_t size;
const std::array<unsigned int, MAX_GFX_PLANES> planeoffset;
};
const static chr_def nintendo_sfc{ 8U, {0U, 1U, 2U, 3U} };
int main() {
// std::array can be used with range-based for
for (auto i : nintendo_sfc.planeoffset) {
std::cout << i << " ";
}
return 0;
}