c++ - 如果 `std::array` 没有采用 `std::initializer_list` 的构造函数,那么初始化如何工作?
问题描述
有很多关于std::array
用 a 初始化数据成员的问题和答案std::initializer_list
,以及它是如何不可能的,因为没有std::array
可用的构造函数。我想知道std::array
then 的初始化是如何工作的?
当进行这样的调用时,引擎盖下会发生什么:
std::array<int, 4> a = {1,2,3,4}; // (1)
如果论证不是std::initializer_list<int>
?
我试图通过查看libstdc++ 源代码来弄清楚初始化是如何工作的,并弄清楚_M_elems
( __array_traits::_Tp
) 做了什么,但我似乎找不到存储数据的数组的实际分配。然而,我看到它被到处使用:
// Element access.
_GLIBCXX17_CONSTEXPR reference
operator[](size_type __n) noexcept
{ return _AT_Type::_S_ref(_M_elems, __n); }
并且_S_ref
是一个constexpr
似乎返回的函数nullptr
?
实际的数组数据在哪里声明?我可以理解编译器是否在幕后做某事,因为所有构造函数都是自动生成的,但我想知道会发生什么以及初始化调用 (1) 是如何可能的。
此外,如果我使用 anstd::array
作为 N 维的数据成员Point
,我找到了一个答案,建议如下:
template<std::size_t N, typename BT=double>
class Point
{
public:
Point() = default;
template<typename ... Args>
Point(Args&& ... args)
:
values_{std::forward<Args>(args)...}
{}
private:
std::array<BT, N> values_;
};
这使得可以做
Point<1> P1 {1.}; // (2)
Point<3> P3 {1.,2.,3.}; // (3)
我知道转发是必需的,因为(我理解为)(2,3)中使用的初始化列表是左值。但是,为什么需要大括号?如果我使用圆括号初始化values_
values_(std::forward<Args>(args)...)
我明白了
main.cpp: In instantiation of ‘Point<N, BT>::Point(Args&& ...) [with Args = {double}; long unsigned int N = 1; BT = double]’:
main.cpp:37:20: required from here
main.cpp:14:48: error: no matching function for call to ‘std::array<double, 1>::array(double)’
values_(std::forward<Args>(args)...)
解决方案
推荐阅读
- javascript - React:如何设置对象属性的状态?
- regex - 使用 RegEx 和 Beautiful Soup 查找锚文本 - RegEx 无法按预期工作
- python-3.x - 使用 joblib 时 time.time() 库返回意外结果
- rust - 为什么 rust 在引用可变变量时会重新声明可变性?
- javascript - 根据输入文本字段的焦点反应条件渲染
- perl - Perl,将字符串拆分为键:值对,用于带有小写键的散列,没有临时数组
- c - c中不熟悉的函数声明
- javascript - Vue.js,找不到方法内部的函数
- java - 为什么检查哈希集是否已添加为布尔值返回 false
- vb.net - 更改复选框时预览不同的文本