我想用初始化列表初始化一个对象。问题是,初始化列表能够包含不可预测数量的元素,但我只需要为变量初始化。用户可以发送任意数量的列表元素,我只需要其中的四个。
我编写了以下代码,但对我来说看起来很长很慢。有没有更好的方法呢?
Pixel::Pixel(std::initializer_list<uint8_t> Channels)
{
switch (Channels.size())
{
case 0:
R = 0;
G = 0;
B = 0;
A = 0;
break;
case 1:
R = *(Channels.begin() + 0);
G = 0;
B = 0;
A = 0;
break;
case 2:
R = *(Channels.begin() + 0);
G = *(Channels.begin() + 1);
B = 0;
A = 0;
break;
case 3:
R = *(Channels.begin() + 0);
G = *(Channels.begin() + 1);
B = *(Channels.begin() + 2);
A = 0;
break;
default:
R = *(Channels.begin() + 0);
G = *(Channels.begin() + 1);
B = *(Channels.begin() + 2);
A = *(Channels.begin() + 3);
}
}
(注意:我知道这可以通过使用四个单独的参数传递R,G,B,A值来完成。但我的主要目的是学习如何使用初始化列表功能执行此操作。)
答案 0 :(得分:4)
使用std::initialiser_list
struct Pixel
{
Pixel(std::initializer_list<uint8_t> rgba)
: _rgba { rgba }
{
switch(_rgba.size()) {
case 0: _rgba.push_back(0);
case 1: _rgba.push_back(0);
case 2: _rgba.push_back(0);
case 3: _rgba.push_back(0);
case 4: break;
default:
throw std::invalid_argument { "" };
}
}
std::vector<uint8_t> _rgba;
};
......但......
解决这个问题的正确方法可能就是:
struct Pixel
{
Pixel(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, uint8_t a = 0)
: R(r)
, G(g)
, B(b)
, A(a)
{}
uint8_t R,G,B,A;
};
,因为
的示例:
int main()
{
Pixel p1 { 10, 20, 5, 255 };
Pixel p2 { 10, 20, 5 };
Pixel p3 { 10, 20 };
Pixel p4 { 10 };
Pixel p5 { };
Pixel pv1 ( 10, 20, 5, 255 );
Pixel pv2 ( 10, 20, 5 );
Pixel pv3 ( 10, 20 );
Pixel pv4 ( 10 );
Pixel pv5;
return 0;
}
答案 1 :(得分:3)
您可以按以下步骤重写切换:
Pixel::Pixel(std::initializer_list<uint8_t> Channels) : R(0), G(0), B(0), A(0)
{
switch (Channels.size())
{
default: // Too many args
case 4: A = *(Channels.begin() + 3); // No break: Follow next line
case 3: B = *(Channels.begin() + 2); // No break: Follow next line
case 2: G = *(Channels.begin() + 1); // No break: Follow next line
case 1: R = *(Channels.begin() + 0);
case 0: break;
}
}