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

标签 c++ arrays templates initialization c++11

(注:本题为不指定元素个数,仍允许嵌套类型直接初始化。)
This question讨论了像 int arr[20]; 这样的 C 数组的用途.在 his answer ,@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> ( or your own variants ),你甚至不需要考虑它的大小。

现在,是否有任何(可能是 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)

可以找到一个例子here .

但是,正如@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} };

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

最佳答案

我能想到的最好的是:

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

关于c++ - 如何使用 std::array 模拟 C 数组初始化 "int arr[] = { e1, e2, e3, ... }"行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50045985/

相关文章:

c++ - 指向数组第一个元素的指针的地址?

java - 创建通用堆栈数组

Java如何将从字符串数组返回的随机项保存为变量?

c++ - 为通用数据类型创建我自己的迭代器

c++ - 可能的模板解决方案

c++ - 将类型存储为变量?对于模板类?

c++ - 是否可以禁止修改 for 循环体内的循环变量?

c++ - 无法在 cmake 中包含外部先前构建的 .a 库

javascript - 如何使用javascript获取Json对象中字符串的实例数

c++ - graphics.h 没有输出