c++ - 数组与 std::initializer_list 作为函数参数

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

我可以通过两种方式编写一个将临时数组(例如 {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;

是否有任何指南可以告诉您哪个更好?

最佳答案

它们是完全不同的东西。还有 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 种不同的方法来获取一堆 T

它们各有优缺点。

最接近严格更好的是 foo_a 而不是 foo_cfoo_c 的优点仅在于它与 C 风格的数组更兼容。

foo_b 允许您使用除 foo_f 之外的任何其他内容。这很好。

a、c 和 f 在 foo 中都有编译时确定的长度。这可能会有所不同,具体取决于您在做什么。理论上您可以编写一个处理固定长度的 foo_b 类型的 View ,但没有人会为此烦恼。

e 是唯一在调用点支持动态长度的。

f 支持不同的类型,但会使迭代变得不那么干净。

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

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

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

关于c++ - 数组与 std::initializer_list 作为函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51353677/

相关文章:

c++ - 如何在链接时修复 Makefile 错误 'unrecognized reference'?

c++ - 在 C++11 中使用数组初始化列表作为临时列表?

javascript - 突变(["hello", "Hello"]); - 如果 Hello 等于 hello 但我的代码返回 false,则返回 true?

c++ - 为什么 shiboken2 会忽略 C++11 风格的回调?

c++ - 如何编写替换链式方法调用的可变参数方法?

c++ - 如何避免辅助函数被警告? "xxx defined but not used"

c++ - 使用 cin >> 和 cout << 填充 C++ 类的字段

java - 为什么 Java 中的 contains() 方法不能按预期工作?

arrays - Swift Array.insert 泛型

具有右值引用的 C++ 模板化方法消歧规则