将包含C样式数组的对象初始化为成员变量(C++)
Initialize object containing C-style array as member variable (C++)
考虑以下代码:
struct Color // This struct can't be modified
{
double grey;
double rgb[3];
};
int main()
{
double myRGB[3] = {2, 6, 9};
Color c = {10, myRGB}; // This line doesn't work
return 0;
}
如何在一行中初始化Color
对象?
在我的真实场景中,不能更改Color
结构(例如,使用std::array
而不是C样式数组(。
由于Color
是一个聚合,您可以使用聚合初始化,并将数组初始化器直接放在大括号中,如
Color c = {10, {2, 6, 9}};
如果必须用数组初始化c
,由于它很小,您可以像一样展开它
Color c = {10, {myRGB[0], myRGB[1], myRGB[2]}};
假设需要使用中间数组,下面是如何做到的:
#include <utility>
#include <cstddef>
struct Color //this struct can't be modified
{
double grey;
double rgb[3];
};
template<size_t N, size_t... IX>
auto make_c_impl(double grey, double (&rgb)[N], std::index_sequence<IX...>) {
static_assert(sizeof(rgb) == sizeof(Color::rgb), "Arrays sizes must match!");
return Color{grey, {rgb[IX]...}};
}
template<size_t N>
auto make_c(double grey, double (&rgb)[N]) {
return make_c_impl(grey, rgb, std::make_index_sequence<N>{});
}
double myRGB[3] = {2, 6, 9};
Color c = make_c(10, myRGB); //this line now works
请注意,在任何级别的优化下,此代码实际上都不会产生任何不必要的复制。
作为对其他答案的补充,错误是因为在c++中,数组是不可复制的,并且尝试从lvalue
初始化数组具有调用copy-constructor
的语义,与相同
double r1[3] = {0., 0., 0.};
double r2[3] {r1} // doesn't compile
您的选择是:
- 像@NathanOliver那样做
list-initialization
- 或者如@SergeyA答案中那样扩展数组的元素以形成CCD_ 9
说我是骗子,但是。。。
struct Color final
{
double grey;
double rgb[3];
};
// the cheet
#define make_color( x, a, b ) Color x { a, b[0], b[1], b[2] }
int main()
{
double myRGB[3]{ 2, 6, 9 };
make_color( c, 10, myRGB ) ; // single line construction
printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ;
}
但是,由于这是一个非常糟糕的C++,我自由地制作了一些稍微好一点的东西。。。
struct Color final
{
double grey;
double rgb[3];
};
auto make_color ( double a, const double(&b)[3] ) { return Color { a, b[0], b[1], b[2] }; };
auto make_color ( double a, double b, double c, double d ) { return Color { a, b, c, d }; };
auto print_color ( Color c ) { printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ; }
//
int main()
{
double myRGB[3]{ 2, 6, 9 };
auto c = make_color( 10, myRGB ) ;
print_color(c);
auto z = make_color( 10, 0xFF, 0xA0, 0xB0 ) ;
print_color(z);
}
所有这些都是一个好的老SO传统:不要质疑这个问题:(
(此处为必填Wandbox(
ps:我喜欢你的方法Oliver,当然你在那些init列表中不需要双大括号。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 将包含C样式数组的对象初始化为成员变量(C++)
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 在循环中按顺序遍历成员变量
- c++类声明时,相同的例程,不同的成员变量类型
- 如何从另一个文件继承私有成员变量和公共函数
- 在C++类中,是否必须初始化作为数组的成员变量
- 如何从子成员函数修改父公共成员变量
- 我可以在 C++ 中将数据成员/变量从其定义之外添加到结构中吗?
- 从私有成员变量的成员方法返回unique_ptr
- 在派生类中使用基类的私有成员变量的最佳方法
- 静态 constexpr 类成员变量对多线程读取是否安全?
- C++:是否可以使用非静态成员变量模板?
- 打印所有继承的类成员变量和方法
- 如何在复杂继承中访问静态成员变量
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 成员变量与函数概念检查