C++ 作为数组的函数参数传递的初始化器列表
我如何使其工作:C++ 作为数组的函数参数传递的初始化器列表,c++,c++11,initializer-list,C++,C++11,Initializer List,我如何使其工作: void foo(uint8_t a[]) { ... } foo({0x01, 0x02, 0x03}); 这给了我一个错误: error: cannot convert '<brace-enclosed initializer list>' to 'uint8_t* {aka unsigned char*}' for argument '1' ^ 错误
void foo(uint8_t a[]) { ... }
foo({0x01, 0x02, 0x03});
这给了我一个错误:
error: cannot convert '<brace-enclosed initializer list>' to 'uint8_t* {aka unsigned char*}' for argument '1'
^
错误:无法将参数“1”的“”转换为“uint8_t*{aka unsigned char*}”
^
您不能。
刚构
uint8_t a[] = {0x01, 0x02, 0x03};
并调用foo(a)
或者只使用
std::array
,这可能更好。这对我来说很有效,我不得不更改函数签名,但在我的情况下,它实际上更好,因为它静态检查数组长度:
void foo(std::array<uint8_t, 3> a) { /* use a.data() instead of a */ }
foo({0x01, 0x02, 0x03}); // OK
foo({0x01, 0x02}); // Works, at least on GCC 4.9.1. The third value is set to zero.
foo({0x01, 0x02, 0x03, 0x04}); // Compilation error.
void foo(std::array a){/*使用a.data()而不是*/}
foo({0x01,0x02,0x03});//好啊
foo({0x01,0x02});//至少在GCC 4.9.1中有效。第三个值设置为零。
foo({0x01,0x02,0x03,0x04});//编译错误。
到目前为止,答案还没有解决签名中的主要问题
void foo(uint8_t a[])
a
不是数组,而是指向uint8\t
的指针。尽管a
的声明使它看起来像一个数组,但这是事实。错误消息甚至指出了这一点:
cannot convert '<brace-enclosed initializer list>' to 'uint8_t* {aka unsigned char*}'
不能调用foo({0x01、0x02、0x03})代码>带有上面的签名
<>我建议你花些时间读C风格数组,以及它们在C++中的用法。
从您发布到自己问题的答案来看,您似乎在寻找一个适用于固定大小数组的函数。但不要按价值传递它!我建议使用以下声明:
void foo(std::array<uint8_t, 3> const &a);
void foo(std::array const&a);
这是:
void foo(uint8_t a[]) { ... }
是一个接受uint8\u t*
的函数,而不是数组-数组用作函数参数时会衰减为指针。问题是不能将初始值设定项列表(如{0x01、0x02、0x03}
)转换为uint8\u t*
如果要将任意数量的uint8\t
s传递给foo
,简单的解决方案是使用新的
foo(std::array{0x01,0x02,0x03}.data())代码>C型阵列在任何方面都很糟糕。如果可能的话,请始终在它们上面使用std::array。也许你可以使用像template void foo(std::array a){/*…*/}
..(我以前从未尝试过这种方法)@Shindou在这种情况下,无法推断大小
参数。@ForEveR我刚刚测试过。我们必须像foo({/*…*/})那样称呼它代码>使之成功work@Shindou:这正是他刚才所说的如果您避免混淆的uint8\u t[]
参数“type”并编写更准确的uint8\u t*
,问题会更清楚。:)抱歉,是的,我通常会使用指针形式,但我想知道如果改用数组语法,编译器是否会执行一些我不知道的魔法。不,100%等效。std::array在函数之前创建,直到函数返回为止。
void foo(uint8_t a[]) { ... }
void foo(std::initializer_list<uint8_t> a) { ... }
foo({0x01, 0x02, 0x03, 0x04, 0x05}); // OK - a has 5 elems in it
template <typename... Args,
typename = std::enable_if_t<
all_true<std::is_convertible<Args, uint8_t>::value...>
>>
void foo(Args... elems) {
uint8_t a[] = {elems...};
// ...
}
foo({0x01, 0x02, 0x03}); // error
foo(0x01, 0x02, 0x03; // OK - a has 3 elems in it