繁体   English   中英

使用 std::index_sequence 进行 std::array 初始化的包扩展

[英]Pack expansion for std::array initialization using std::index_sequence

我需要使用相同的构造函数 arguments 初始化一个带有 N 个对象的 std:array,如std::vector<T>(size_t, {args...}) 从我在这里的搜索中我想出了这个,它有效:

template<typename T, size_t... Ints, typename... Args>
std::array<T, sizeof...(Ints)> make_array_(std::index_sequence<Ints...>, Args&&... args) {
    return { (Ints, T{args...})... };
}

template<typename T, size_t N, typename... Args>
std::array<T, N> make_array(Args&&... args) {
    return make_array_<T>(std::make_index_sequence<N>(), args...);
}

struct AStruct {
    AStruct(int a, float b) : a_{ a }, b_{ b } {}
private:
    int a_; float b_;
}

int main() {
    auto anArray = make_array<AStruct, 10>(8, 5.4f);
    // etc...
}

但我不明白第三行。 (Ints, T{args...})...如何转换为T{args...}, T{args...}, T{args...}... N 次?

外部参数包没有以您编写的方式扩展,它像这样扩展(内部包未显示扩展,因为您似乎对此没有问题):

return { (0, T{args...}), (1, T{args...}), (2, T{args}) };

其中整数的类型为std::size_t

(0, T{args...})是大括号括起来的初始值设定项的一个元素。 它是使用逗号运算符的表达式。 逗号运算符首先评估左侧( 0 ),然后评估右侧( T{args...} ),然后返回后者。

因为0的评估没有副作用,并且它的值被逗号运算符丢弃,这实际上相当于

return { T{args...}, T{args...}, T{args...} };

对此有一个警告。 逗号运算符可以重载。 如果有一个重载接受std::size_t作为第一个参数和T作为第二个参数,那么这将以意想不到的方式表现,而是用重载的结果初始化返回值。 这可以通过将 integer 强制转换为void来防止(它永远不会作为重载运算符调用的参数出现):

return { (void(Ints), T{args...})... };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM