【发布时间】:2018-06-11 12:07:57
【问题描述】:
受this question 的启发,我想知道如果T 和N 都是模板参数并且T 不是默认可构造的,那么在构造函数初始化列表中构造std::array<T,N> 是否安全。我想出了以下辅助函数:
template <typename T, size_t... I>
constexpr auto make_array_impl(std::index_sequence<I...>, const T& val) {
return std::array<T, sizeof...(I)>{ (I, val)... };
}
template <typename T, size_t N>
constexpr auto make_array(const T& val) {
return make_array_impl<T>(std::make_index_sequence<N>{}, val);
}
现在,如果我有这样的课程:
class E {
public:
E() = delete;
E(int, int, int) { }
};
我会写:
template <typename T, size_t N>
class A {
public:
template <typename... Args>
A(Args&&... args) : a_(make_array<T, N>(T(std::forward<Args>(args)...))) { }
private:
std::array<T, N> a_;
};
然后
A<E, 5> a(1, 2, 3);
这适用于我启用 GCC 8.1 / Clang 6.0 和 C++14。但是,我不确定构造函数初始化列表中a_的这种初始化是否正确,如果正确,这种正确性是否取决于模板参数T。
(说实话,我什至在标准中都找不到std::array是否可以被另一个std::array初始化。它是聚合初始化的一部分吗?或者,std::array是否支持复制初始化?)
为了澄清这个问题,我想通过什么来实现
A<E, 5> a(1, 2, 3);
a::a_ 成员函数是否会被有效地启动为
std::array<E, 5> a::a_ = { E(1,2,3), E(1,2,3), E(1,2,3), E(1,2,3), E(1,2,3) };
【问题讨论】:
-
当
N!= 1 时,您不希望完美转发,否则您将多次从同一个源右值移动。 -
@ildjarn 感谢您指出这一点,我更新了代码。
标签: c++ arrays initializer-list