【问题标题】:array vs std::initializer_list as function parameter数组与 std::initializer_list 作为函数参数
【发布时间】:2018-12-23 12:29:21
【问题描述】:

我可以通过两种方式编写一个将临时数组(例如{1, 2, 3})作为参数的函数:

// using array
template<typename T, int N>
auto foo1(const T(&t)[N]) -> void;

// using std::initializer_list
template<typename T>
auto foo2(std::initializer_list<T> t) -> void;

是否有任何指导方针可以说明哪个更好?

【问题讨论】:

  • 参见here,例如。
  • 在第一个中你可以使用长度作为编译时常量,在第二个中你不能。相反,第一个不能接受长度未知的列表。
  • @MM 不确定我是否理解该评论。
  • @PaulSanders 在 foo2 中尝试 std::array&lt;T, t.size()&gt; x;(并调用它)
  • @MM 好的,谢谢,我现在明白了。因此,通过不时从栏杆后面探出头来,我们学习了。

标签: c++ arrays c++11 initializer-list


【解决方案1】:

它们都是非常不同的东西。还有2、3个其他的选择是合理的。

template<class T, std::size_t N>
void foo_a( std::array<T, N> const& );

template<class T>
void foo_b( gsl::span<const T> );

template<class T, std::size_t N >
void foo_c( T const(&)[N] );

template<class T>
void foo_d( std::initializer_list<T> );

template<class T, class A=std::allocator<T> >
void foo_e( std::vector<T, A> const& );

template<class...Ts>
void foo_f( std::tuple<Ts...> const& );

template<class...Ts>
void foo_g( Ts const& ... );

这里有 7 种不同的方式来获取一堆Ts。

它们各有优缺点。

最接近严格更好的是foo_a超过foo_cfoo_c 唯一的好处在于它更兼容 C 风格的数组。

foo_b 允许您使用除foo_f 之外的任何其他人。所以这很好。

a、c 和 f 在foo 内都有编译时确定的长度。这可能会有所不同,具体取决于您在做什么。理论上你可以编写一个foo_b 类型的视图来处理固定长度,但没人会打扰。

e 是唯一支持呼叫站点动态长度的。

f 支持不相同的类型,但会使迭代不太干净。

所有这些都可以稍作修改以允许移出(即使是初始化器列表也有更多样板)。

d 给出最简单的{},但 g 一样干净(完全省略 {})。

通常我使用自制的gsl::span 变体。它有一个initializer_list 构造函数。而且我很少想推断T

【讨论】:

    猜你喜欢
    • 2011-01-22
    • 2013-10-29
    • 2016-05-31
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多