如何使用 std::array 模拟 C 数组初始化“int arr\[\] = { e1, e2, e3, ... }”行为?

新手上路,请多包涵

(注意:这个问题是关于不必指定元素的数量并且仍然允许直接初始化嵌套类型。)

这个问题 讨论了 C 数组的用途,例如 int arr[20]; 。在 他的回答 中,@James Kanze 展示了 C 数组的最后一个据点之一,它具有独特的初始化特征:

 int arr[] = { 1, 3, 3, 7, 0, 4, 2, 0, 3, 1, 4, 1, 5, 9 };

我们不必指定元素的数量,万岁!现在使用 C++11 函数 std::beginstd::end<iterator>或您自己的变体)对其进行迭代,您甚至不需要考虑它的大小.

现在,是否有任何(可能是 TMP)方法可以实现与 std::array 相同的效果?允许使用宏使其看起来更好。 :)

 ??? std_array = { "here", "be", "elements" };


编辑:根据各种答案编译的中间版本,如下所示:

 #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 东西:

  • 可变参数模板
  • sizeof...
  • 右值引用
  • 完美转发
  • std::array 当然
  • 统一初始化
  • 使用统一初始化省略返回类型
  • 类型推断( auto

一个例子可以在 这里 找到。

但是,正如@Johannes 在对@Xaade 答案的评论中指出的那样,您不能使用这样的函数初始化嵌套类型。例子:

 struct A{ int a; int b; };

// C syntax
A arr[] = { {1,2}, {3,4} };
// using std::array
??? std_array = { {1,2}, {3,4} };

此外,初始化器的数量受限于实现支持的函数和模板参数的数量。

原文由 Xeo 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 421
1 个回答

我能想到的最好的是:

 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++ 编译器都能够对其进行优化,使其与直接初始化一样快。

原文由 Pavel Minaev 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题