如何模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }"std::array 的行为? [英] How to emulate C array initialization "int arr[] = { e1, e2, e3, ... }" behaviour with std::array?
问题描述
(注意:这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型.)
这个问题讨论了像 int arr[20];
这样的 C 数组的剩余用途.在 他的回答,@James Kanze 展示了 C 数组的最后据点之一,它独特的初始化特性:
(Note: This question is about not having to specify the number of elements and still allow nested types to be directly initialized.)
This question discusses the uses left for a C array like int arr[20];
. On his answer, @James Kanze shows one of the last strongholds of C arrays, it's unique initialization characteristics:
int arr[] = { 1, 3, 3, 7, 0, 4, 2, 0, 3, 1, 4, 1, 5, 9 };
我们不必指定元素的数量,万岁!现在使用来自
(或你自己的变体)和你永远不需要考虑它的大小.
We don't have to specify the number of elements, hooray! Now iterate over it with the C++11 functions std::begin
and std::end
from <iterator>
(or your own variants) and you never need to even think of its size.
现在,是否有任何(可能是 TMP)方法可以使用 std::array
实现相同的效果?允许使用宏使其看起来更好.:)
Now, are there any (possibly TMP) ways to achieve the same with std::array
? Use of macros allowed to make it look nicer. :)
??? std_array = { "here", "be", "elements" };
<小时>
编辑:从各种答案编译的中间版本,看起来像这样:
Edit: Intermediate version, compiled from various answers, looks like this:
#include <array>
#include <utility>
template<class T, class... Tail, class Elem = typename std::decay<T>::type>
std::array<Elem,1+sizeof...(Tail)> make_array(T&& head, Tail&&... values)
{
return { std::forward<T>(head), std::forward<Tail>(values)... };
}
// in code
auto std_array = make_array(1,2,3,4,5);
并使用了各种很酷的 C++11 东西:
And employs all kind of cool C++11 stuff:
- 可变模板
sizeof...
- 右值引用
- 完美转发
std::array
,当然- 统一初始化
- 使用统一初始化省略返回类型
- 类型推断(
auto
)
可以在此处找到示例.
但是,正如@Johannes 在对@Xaade 的回答的评论中指出的那样,您不能使用这样的函数初始化嵌套类型.示例:
However, as @Johannes points out in the comment on @Xaade's answer, you can't initialize nested types with such a function. Example:
struct A{ int a; int b; };
// C syntax
A arr[] = { {1,2}, {3,4} };
// using std::array
??? std_array = { {1,2}, {3,4} };
此外,初始化器的数量受限于实现支持的函数和模板参数的数量.
Also, the number of initializers is limited to the number of function and template arguments supported by the implementation.
推荐答案
我能想到的最好的是:
template<class T, class... Tail>
auto make_array(T head, Tail... tail) -> std::array<T, 1 + sizeof...(Tail)>
{
std::array<T, 1 + sizeof...(Tail)> a = { head, tail ... };
return a;
}
auto a = make_array(1, 2, 3);
但是,这需要编译器做NRVO,然后还要跳过返回值的拷贝(这也是合法的但不是必需的).在实践中,我希望任何 C++ 编译器都能够对其进行优化,使其与直接初始化一样快.
However, this requires the compiler to do NRVO, and then also skip the copy of returned value (which is also legal but not required). In practice, I would expect any C++ compiler to be able to optimize that such that it's as fast as direct initialization.
这篇关于如何模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }"std::array 的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!