使用带有初始化列表的std::array
Using std::array with initialization lists
除非我弄错了,应该可以通过以下方式创建std:数组:
std::array<std::string, 2> strings = { "a", "b" };
std::array<std::string, 2> strings({ "a", "b" });
然而,使用GCC 4.6.1,我无法让这些工作。编译器简单地说:
expected primary-expression before ',' token
和初始化列表在std::vector中工作得很好。那么到底是哪一个呢?是我错误地认为std::array应该接受初始化列表,还是GNU标准c++库团队犯了错误?
std::array
很有趣。它的定义基本上是这样的:
template<typename T, int size>
struct std::array
{
T a[size];
};
是一个包含数组的结构体。它没有接受初始化列表的构造函数。但是根据c++ 11的规则,std::array
是一个聚合,因此它可以通过聚合初始化来创建。要在结构体内部聚合初始化数组,需要第二组花括号:
std::array<std::string, 2> strings = {{ "a", "b" }};
请注意,标准确实建议在这种情况下可以省略额外的大括号。
添加到可接受的答案中:
std::array<char, 2> a1{'a', 'b'};
std::array<char, 2> a2 = {'a', 'b'};
std::array<char, 2> a3{{'a', 'b'}};
std::array<char, 2> a4 = {{'a', 'b'}};
都可以在GCC 4.6.3 (Xubuntu 12.01)上工作。然而,
void f(std::array<char, 2> a)
{
}
//f({'a', 'b'}); //doesn't compile
f({{'a', 'b'}});
上面的需要双括号来编译。带有单大括号的版本会导致以下错误:
../src/main.cc: In function ‘int main(int, char**)’:
../src/main.cc:23:17: error: could not convert ‘{'a', 'b'}’ from ‘<brace-enclosed initializer list>’ to ‘std::array<char, 2ul>’
我不确定类型推断/转换的哪个方面使事情以这种方式工作,或者这是否是GCC实现的一个怪癖。
有点晚了,但这是我在c++ 17中做的。不使用初始化列表,只使用可变值列表。如下所示:auto ar2 = create_array(1,2,3,4);
#include <array>
#include <type_traits>
namespace traits
{
template<typename T, typename... Ts>
struct array_type
{
using type = T;
};
template<typename T, typename... Ts>
static constexpr bool are_same_type()
{
return std::conjunction_v<std::is_same<T, Ts>...>;
}
}
template<typename... T>
constexpr auto create_array(const T&&... values)
{
using array_type = typename traits::array_type<T...>::type;
static_assert(sizeof...(T) > 0, "an array must have at least one element");
static_assert(traits::are_same_type<T...>(), "all elements must have same type");
return std::array<array_type, sizeof...(T)>{ values... };
}
template<typename T, typename... Ts>
constexpr auto create_array_t(const Ts&&... values)
{
using array_type = T;
static_assert(sizeof...(Ts) > 0, "an array must have at least one element");
static_assert(traits::are_same_type<Ts...>(), "all elements must have same type");
return std::array<array_type, sizeof...(Ts)>{ static_cast<T>(values)... };
}
// to create a std::array of specific type
auto ar = create_array_t<std::uint8_t>(1u, 2u, 3u, 4u);
static_assert(ar.size() == 4);
// to create an array and let the compiler deduce its type
auto ar2 = create_array(1, 2, 3, 4);
static_assert(ar2.size() == 4);
相关文章:
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 将std ::列表附加到std ::列表的向量中
- STD ::列表对其分配器参数有什么作用
- swig-包装到c#时,没有默认的std ::列表,我该怎么做
- 调用具有std ::列表为参数的C 函数
- STD ::列表和垃圾收集算法
- 低于20亿的质量 - 使用STD ::列表阻碍性能
- C 按其值对object的std ::列表进行排序
- 如何在(C )构造函数参数列表中包含std:列表
- 如何使用迭代器插入std ::列表
- C STD ::列表分割故障
- 将带有指针的 STD 列表复制到另一个带有指针的 STD 列表
- 比较std::对的2个std::列表
- 在 std 列表中查找对象并将其添加到另一个列表
- 与内存堆有关的C 链接列表(STD ::列表)是否使用新的
- 使用STD ::列表作为循环列表安全吗?
- C++当类型T需要构造函数时,是否可以创建类型T的std::列表
- 从对象指针的 STD 列表中擦除对象
- 如何从std::列表中删除项目
- 正在从std::unique_pointer的std::列表中删除元素