Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 固定大小和零初始化数组作为C++;11_C++_Arrays_C++11_Initializer List_Default Arguments - Fatal编程技术网

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}){}