C++ 为什么std::array<;国际,10>;x不是零初始化的,而是std::array<;国际,10>;x=std::数组<;国际,10>;()好像是?
我刚才问了两个关于数组和值初始化的问题。 但是有了这个密码,我就迷路了:C++ 为什么std::array<;国际,10>;x不是零初始化的,而是std::array<;国际,10>;x=std::数组<;国际,10>;()好像是?,c++,arrays,c++11,initialization,default-value,C++,Arrays,C++11,Initialization,Default Value,我刚才问了两个关于数组和值初始化的问题。 但是有了这个密码,我就迷路了: #include <iostream> #include <iomanip> #include <array> template <class T, class U = decltype(std::declval<T>().at(0))> inline U f1(const unsigned int i) {T x; return x.at(i);} temp
#include <iostream>
#include <iomanip>
#include <array>
template <class T, class U = decltype(std::declval<T>().at(0))>
inline U f1(const unsigned int i)
{T x; return x.at(i);}
template <class T, class U = decltype(std::declval<T>().at(0))>
inline U f2(const unsigned int i)
{T x = T(); return x.at(i);}
int main()
{
static const unsigned int n = 10;
static const unsigned int w = 20;
for (unsigned int i = 0; i < n; ++i) {
std::cout<<std::setw(w)<<i;
std::cout<<std::setw(w)<<f1<std::array<int, n>>(i);
std::cout<<std::setw(w)<<f2<std::array<int, n>>(i);
std::cout<<std::setw(w)<<std::endl;
}
return 0;
}
我个人认为f2
将创建一个具有任意值的数组,并将其复制/移动到x
。但事实似乎并非如此
因此,我有两个问题:
- 为什么?
- C++11
和C-stylestd::array
在这种情况下是否具有相同的行为T[N]
{}
或()
作为初始值设定项,而不使用=
,则会导致值初始化。对于具有隐式声明构造函数的类型,值初始化实现零初始化,顾名思义,它将每个基元元素设置为0
。这发生在构造函数可以运行之前,但是在这种情况下,构造函数什么也不做
因为构造函数什么都不做(它很简单),所以可以看到未初始化的数据
对于C样式数组,如果使用
={}
而不是=T()
,则行为类似,因为后者是非法的T()
将要求将临时数组对象分配给命名对象,但无法分配数组<另一方面,code>={}将带括号的初始值设定项列表分配给数组,带括号的初始值设定项列表是一种特殊的语法结构,既不是表达式也不是对象。T()
是一个初始化的值T
。如果T
是C样式数组类型,则语法无效<代码>tx={}代码>或tx{}代码>是更普遍适用的语法。@Casey值初始化适用于C样式数组<如果T
不是简单的类型说明符,即命名类型的单个标识符或关键字,则code>T()
是语法错误。在C++03中,={}
仅适用于数组,简单的{}
是一个错误。假定的重复是关于值初始化的,但这个问题是关于默认初始化的。请重新打开并找到一个正确的副本,或者只回答它。@potatosatter我不建议值初始化不适用于C样式数组。简单类型说明符也可以是type name(包括typedef name)或simple-template-id。问题是关于C++11。请注意,5.2.3/2定义了函数强制转换表示法:“表达式T()
,其中T
是非数组完整对象类型或(可能是cv限定)void
type,创建指定类型的prvalue,该值已初始化(8.5;未对void()
案例进行初始化)。“它明确禁止数组类型。
0 0 0
1 61 0
2 0 0
3 0 0
4 297887440 0
5 32767 0
6 4196848 0
7 0 0
8 297887664 0
9 32767 0