C++ 固定大小和零初始化数组作为C++;11
上下文:我认为使用C++ 固定大小和零初始化数组作为C++;11,c++,arrays,c++11,initializer-list,default-arguments,C++,Arrays,C++11,Initializer List,Default Arguments,上下文:我认为使用compile:g++-std=c++11 main.cpp编译的以下内容将零初始化固定大小的数组arr: void foo(int arr[4] = {0}) { } int main(int argc, char const *argv[]) { foo(); return 0; } 但是,我使用gdb进行调试,发现arr=0x0(null)。我(疯狂地)猜测这是因为int-arr[4]与int*arr非常相似,但另外告诉编译器只允许长度为4的数组。因此
compile:g++-std=c++11 main.cpp编译的以下内容将零初始化固定大小的数组arr
:
void foo(int arr[4] = {0}) { }
int main(int argc, char const *argv[]) {
foo();
return 0;
}
但是,我使用gdb
进行调试,发现arr=0x0
(null)。我(疯狂地)猜测这是因为int-arr[4]
与int*arr
非常相似,但另外告诉编译器只允许长度为4的数组。因此,实际发生的是intarr*={0}
即我只是使用一个初始值设定项列表对指针进行零初始化
我知道我可以通过恢复使用重载而不是默认参数来规避此问题:
void foo(int arr[4]) { }
void foo() {
int arr[4] = {0};
foo(arr);
}
正如预期的那样,这在foo
中为我提供了一个零初始化的固定大小数组。但是,我认为通过使用一些默认参数将这两个重载函数合并为一个会很好,类似于SSCCE
问题:在C++11中是否可以对默认参数固定大小数组进行零初始化。如果是,如何处理?您遇到的主要问题是void foo(int arr[4])
衰减为void foo(int*arr)
,因此您的函数实际上接受的是指针而不是数组。简单的证明是foo(nullptr)代码>将编译而不出现错误或警告
同样地,声明voidfoo(int-arr[4]={0})
实际上是void foo(int*arr={0})
初始化指向0的指针(尝试将{0}
更改为任何其他数字实际上会导致编译时错误)
最好的替代方法是使用std::array
,例如:
#include <array>
void foo(std::array<int, 4> arr = {0}) { }
int main(int argc, char const *argv[]) {
foo();
// call with an array
foo({1,2,3,4});
// providing more values will cause a compile time error
// foo({2,3,4,5,6,7,8});
return 0;
}
#包括
void foo(std::array arr={0}{}
int main(int argc,char const*argv[]{
foo();
//用数组调用
foo({1,2,3,4});
//提供更多值将导致编译时错误
//foo({2,3,4,5,6,7,8});
返回0;
}
请注意,目前没有方便的方法将“原始”C样式数组转换为std::array,尽管在实验/array
中有一个名为std::to_array
的助手函数,它可能会在将来的版本中合并到标准中您遇到的主要问题是void foo(int arr[4])
衰减为void foo(int*arr)
,因此函数实际上接受指针而不是数组。简单的证明是foo(nullptr)代码>将编译而不出现错误或警告
同样地,声明voidfoo(int-arr[4]={0})
实际上是void foo(int*arr={0})
初始化指向0的指针(尝试将{0}
更改为任何其他数字实际上会导致编译时错误)
最好的替代方法是使用std::array
,例如:
#include <array>
void foo(std::array<int, 4> arr = {0}) { }
int main(int argc, char const *argv[]) {
foo();
// call with an array
foo({1,2,3,4});
// providing more values will cause a compile time error
// foo({2,3,4,5,6,7,8});
return 0;
}
#包括
void foo(std::array arr={0}{}
int main(int argc,char const*argv[]{
foo();
//用数组调用
foo({1,2,3,4});
//提供更多值将导致编译时错误
//foo({2,3,4,5,6,7,8});
返回0;
}
请注意,目前没有方便的方法将“原始”C样式数组转换为std::array,尽管在实验/array
中有一个名为std::to_array
的助手函数,该函数可能在将来的版本中合并到标准中这回答了我的问题。但是,应该注意的是,传递的std::array
不会衰减到某个指针中,而是按值进行复制。对于大型数组或对foo的递归调用(我在实际应用程序中就是这样做的),这可能会很慢。这可以通过将std::array
标记为const并将其作为一个引用来解决:void foo(const std::array&arr={0}){}
如果使用const不是一个选项,那么您也许可以将std::array
改为:void foo(std::array&&arr={0}){}
这回答了我的问题。但是,应该注意的是,传递的std::array
不会衰减到某个指针中,而是按值进行复制。对于大型数组或对foo的递归调用(我在实际应用程序中就是这样做的),这可能会很慢。这可以通过将std::array
标记为const并将其作为一个引用来解决:void foo(const std::array&arr={0}){}
如果使用const不是一个选项,那么您也许可以将std::array
改为:void foo(std::array&&arr={0}){}