Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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++ 为什么std::array没有一个构造函数来为数组填充一个值?_C++_C++11_Stdarray - Fatal编程技术网

C++ 为什么std::array没有一个构造函数来为数组填充一个值?

C++ 为什么std::array没有一个构造函数来为数组填充一个值?,c++,c++11,stdarray,C++,C++11,Stdarray,是没有 std::array<T,size>::array(const T& value); 但这不是一个构造函数,内存将首先清零。如果我想要所有的-1都像这样呢?std::array在设计上是一个聚合,因此没有用户声明的构造函数 正如您所说,您可以在默认构造之后使用fill。由于它是一个聚合,默认构造不会将内存归零,但会使其处于未初始化状态(如果包含的类型是可初始化的)。首先,它不是std::array,而是std::array,其中N是编译时常量整数表达式 其次,std

是没有

std::array<T,size>::array(const T& value);

但这不是一个构造函数,内存将首先清零。如果我想要所有的
-1
都像这样呢?

std::array
在设计上是一个聚合,因此没有用户声明的构造函数


正如您所说,您可以在默认构造之后使用
fill
。由于它是一个聚合,默认构造不会将内存归零,但会使其处于未初始化状态(如果包含的类型是可初始化的)。

首先,它不是
std::array
,而是
std::array
,其中
N
是编译时常量整数表达式


其次,
std::array
通过设计聚合。所以它没有任何使它非聚合的东西,这就是为什么它没有构造函数。。。和析构函数、虚拟函数等。

请注意,通过利用数组不是零初始化的,并且有一个复制构造函数和do,您可以有效地模拟这种类型的构造函数

template <size_t N, class T>
array<T,N> make_array(const T &v) {
    array<T,N> ret;
    ret.fill(v);
    return ret;
}

auto a = make_array<20>('z');
模板
阵列制作_阵列(常数T&v){
阵列ret;
重新填充(v);
返回ret;
}
自动a=生成数组('z');

您可以使用
std::index sequence
进行以下操作:

namespace detail
{

    template <typename T, std::size_t...Is>
    constexpr std::array<T, sizeof...(Is)>
    make_array(const T& value, std::index_sequence<Is...>)
    {
        return {{(static_cast<void>(Is), value)...}};
    }
}

template <std::size_t N, typename T>
constexpr std::array<T, N> make_array(const T& value)
{
    return detail::make_array(value, std::make_index_sequence<N>());
}
名称空间详细信息
{
模板
constexpr std::数组
生成数组(常量T和值,标准::索引序列)
{
返回{(static_cast(Is),value)…};
}
}
模板
constexpr std::数组生成数组(const T&value)
{
返回详细信息::make_数组(值,std::make_索引_序列());
}

std::make_index_sequence
是C++14,但可以在C++11中实现


static\u cast(Is)
是处理邪恶的
操作符,
,这可能是
T
提供的。

“内存将首先归零”你确定这是真的吗?除非你要求它,否则它不会首先归零。除了所有答案的聚合参数之外,还可能有更概念性的推理。填充构造函数可能会隐藏一个事实,即它并不是真正构造单个元素。它将首先调用聚合初始化,然后将值复制到元素中,但不能立即复制构造元素(例如,与a
std::vector
)。因为它总是等价于
array();数组。fill(),首先省略构造函数并不会隐藏这一事实。同样相关的是:那么这是错的吗?它明确表示数组的元素是默认初始化的。默认初始化不是POD的init,我认为其他所有元素都是默认构造函数,这取决于声明的点。@rubenvb:是的,它们是默认初始化的,而不是值初始化的。所以,如果它们是微不足道的可初始化的,那么它们将不被初始化。啊,是的。这仍然是标准IMO中一个非常顽皮的部分,它区分了用户类型和内置类型
:/
@rubenvb原始类型都有微不足道的默认初始化。如果需要,用户定义的类型可以以相同的方式工作。这不是区别,而是一致性。让我们不要用不需要的模板参数膨胀调用站点
char
是可以推断出来的,所以你可以只写
make_数组('z')
而不是
make_数组('z')
@Nawaz哦,更好。我应该问一下为什么没有
make_array
而不是
:-)
@Walter:你不能返回任何类型的引用,因为你会返回一个对局部变量的引用。如果
t
不是默认可构造的,那么这就行不通了,而这时你非常需要fill构造函数。这是最有用的答案,当
T
不是默认可构造的,也就是当其他答案不满足时,它也起作用。@ChrisBeck非常同意。这正是我的情况,我对其他答案感到沮丧。这表明up投票并不是万能的。由于使用模板递归,这将无法对大型数组进行编译。如果我需要一个没有默认构造函数的百万元素T数组,我是不是运气不好?即使是一个C数组也可以为我工作。@Michałbrzowski:
std::index_序列
可以用对数实例化而不是线性实例化来实现。编译器可能只有“内部函数”来执行一个实例化。然后,就不再有递归了。@Michałbrzowski:你仍然可以切换到
std::vector
,并且
保留整个大小并
在一个循环中放置回
。至于一百万个元素,堆栈在实践中会因为内存有限而出现问题。
namespace detail
{

    template <typename T, std::size_t...Is>
    constexpr std::array<T, sizeof...(Is)>
    make_array(const T& value, std::index_sequence<Is...>)
    {
        return {{(static_cast<void>(Is), value)...}};
    }
}

template <std::size_t N, typename T>
constexpr std::array<T, N> make_array(const T& value)
{
    return detail::make_array(value, std::make_index_sequence<N>());
}