【发布时间】:2013-08-20 05:10:05
【问题描述】:
我刚刚问了两个关于数组和值初始化的问题here 和here。 但是有了这段代码,我迷路了:
#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{};是更普遍适用的语法。 -
@Casey 值初始化适用于 C 样式数组。如果
T不是简单类型说明符,即命名类型的单个标识符或关键字,则T()是语法错误。在 C++03 中,= {}仅适用于数组,简单的{}是错误的。 -
假设的副本是关于值初始化的,但这个问题是关于默认初始化的。请重新打开并找到正确的副本,或者直接回答。
-
@Potatoswatter 我没有建议值初始化不适用于 C 样式数组。 simple-type-specifier 也可以是 type-name(包括 typedef 名称)或 simple-template-id。问题是关于 C++11。
-
请注意,5.2.3/2 定义了函数转换符号:“表达式
T(),其中T是simple-type-specifier 或typename-specifier 对于 非数组 完整对象类型或(可能是 cv 限定的)void类型,创建指定类型的纯右值,它是值初始化的 ( 8.5;没有对void()案例进行初始化)。”它明确禁止数组类型。
标签: c++ arrays c++11 initialization default-value