我刚刚提出了两个关于数组和值初始化的问题这里和这里。
但是对于这段代码,我感到迷茫:
#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;
}
正如预期的那样,f1
返回任意值,因为它的值没有进行零初始化。但是f2
似乎只返回零值:
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
个人认为f2
将创建一个具有任意值的数组并将其复制/移动到x
。但事实似乎并非如此。
所以,我有两个问题:
- 为什么?
- 在这种情况下,C++11的
std::array<T,N>
和C风格的T[N]
是否具有相同的行为?
T()
是一个经过值初始化的T
。如果T
是 C 风格的数组类型,则会出现无效的语法。更普遍适用的语法是T x = {};
或T x{};
。 - CaseyT()
是语法错误。在 C++03 中,= {}
仅适用于数组,而简单的{}
则是错误的。 - PotatoswatterT()
,其中T
是非数组完整对象类型的 简单类型说明符 或 类型名说明符,或者是(可能带有 cv 限定符的)void
类型,创建指定类型的 prvalue,该 prvalue 是值初始化的(8.5;对于void()
情况不执行任何初始化)。" 它明确禁止数组类型。 - Casey