C++ 如何使用初始化列表构造 std::array 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6893700/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to construct std::array object with initializer list?
提问by HighCommander4
Possible Duplicate:
How do I initialize a member array with an initializer_list?
You can construct an std::array just fine with an initializer list:
您可以使用初始化列表构造一个 std::array 就好了:
std::array<int, 3> a = {1, 2, 3}; // works fine
However, when I try to construct it from an std::initializer_list
as a data member or base object in a class, it doesn't work:
但是,当我尝试从类std::initializer_list
中的数据成员或基对象构造它时,它不起作用:
#include <array>
#include <initializer_list>
template <typename T, std::size_t size, typename EnumT>
struct enum_addressable_array : public std::array<T, size>
{
typedef std::array<T, size> base_t;
typedef typename base_t::reference reference;
typedef typename base_t::const_reference const_reference;
typedef typename base_t::size_type size_type;
enum_addressable_array(std::initializer_list<T> il) : base_t{il} {}
reference operator[](EnumT n)
{
return base_t::operator[](static_cast<size_type>(n));
}
const_reference operator[](EnumT n) const
{
return base_t::operator[](static_cast<size_type>(n));
}
};
enum class E {a, b, c};
enum_addressable_array<char, 3, E> ea = {'a', 'b', 'c'};
Errors with gcc 4.6:
gcc 4.6 的错误:
test.cpp: In constructor 'enum_addressable_array<T, size, EnumT>::enum_addressable_array(std::initializer_list<T>) [with T = char, unsigned int size = 3u, EnumT = E]':
test.cpp:26:55: instantiated from here
test.cpp:12:68: error: no matching function for call to 'std::array<char, 3u>::array(<brace-enclosed initializer list>)'
test.cpp:12:68: note: candidates are:
include/c++/4.6.1/array:60:12: note: std::array<char, 3u>::array()
include/c++/4.6.1/array:60:12: note: candidate expects 0 arguments, 1 provided
include/c++/4.6.1/array:60:12: note: constexpr std::array<char, 3u>::array(const std::array<char, 3u>&)
include/c++/4.6.1/array:60:12: note: no known conversion for argument 1 from 'std::initializer_list<char>' to 'const std::array<char, 3u>&'
include/c++/4.6.1/array:60:12: note: constexpr std::array<char, 3u>::array(std::array<char, 3u>&&)
include/c++/4.6.1/array:60:12: note: no known conversion for argument 1 from 'std::initializer_list<char>' to 'std::array<char, 3u>&&'
How can I get it to work so that my wrapper class can be initialized with an initializer-list, as such:
我怎样才能让它工作,以便我的包装类可以使用初始化列表进行初始化,如下所示:
enum_addressable_array<char, 3, E> ea = {'a', 'b', 'c'};
采纳答案by Johannes Schaub - litb
An std::array<>
has no constructor that takes an std::initializer_list<>
(initializer list constructor) and there is no special language support for what it may mean to pass a std::initializer_list<>
to a class' constructors such that that may work. So that fails.
Anstd::array<>
没有接受std::initializer_list<>
(初始化列表构造函数)的构造函数,并且没有特殊的语言支持将 a 传递std::initializer_list<>
给类的构造函数以便可以工作。所以失败了。
For it to work, your derived class needs to catch all elements and then forward them, a constructor template:
为了让它工作,你的派生类需要捕获所有元素然后转发它们,一个构造函数模板:
template<typename ...E>
enum_addressable_array(E&&...e) : base_t{{std::forward<E>(e)...}} {}
Note that you need {{...}}
in this case because brace elision (omitting braces like in your case) does not work at that place. It's only allowed in declarations of the form T t = { ... }
. Because an std::array<>
consists of a struct embedding a raw array, that will need two level of braces. Unfortunately, I believe that the exact aggregate structure of std::array<>
is unspecified, so you will need to hope that it works on most implementations.
请注意,{{...}}
在这种情况下您需要,因为大括号省略(在您的情况下省略大括号)在那个地方不起作用。它只允许在形式的声明中使用T t = { ... }
。因为 anstd::array<>
由一个嵌入原始数组的结构组成,所以需要两级大括号。不幸的是,我相信 的确切聚合结构std::array<>
未指定,因此您需要希望它适用于大多数实现。
回答by Jason
Since a std::array
is a structure that contains an aggregate (it is not an aggregate itself, and does not have a constructor that takes a std::initializer_list
), you can initialize the underlying aggregate inside the structure with an initializer list using a double-braces syntax like so:
由于 astd::array
是一个包含聚合的结构(它本身不是聚合,并且没有接受 a 的构造函数std::initializer_list
),因此您可以使用双大括号语法使用初始化列表初始化结构内的底层聚合,如下所示:
std::array<int, 4> my_array = {{1, 2, 3, 4}};
Note that this is not using std::initializer_list
... this is simply using a C++ initializer list to initialize the publicly accessible array member of std::array
.
请注意,这不是使用std::initializer_list
......这只是使用 C++ 初始化列表来初始化std::array
.
回答by R. Martinho Fernandes
An std::array
does not have a constructor that takes an std::initializer_list
. It's a good thing, because initializer lists can be bigger than the fixed-size of the array.
Anstd::array
没有接受std::initializer_list
. 这是一件好事,因为初始化列表可以大于数组的固定大小。
You can initialize it by testing that the initializer list is not larger than the size of the array and then copying the elements of initializer list to the elems
member of std::array
with std::copy
.
您可以通过测试初始化列表不大于数组的大小,然后将初始化列表的元素复制到with的elems
成员来初始化std::array
它std::copy
。