如果`std :: array`没有使用`std :: initializer_list`的构造函数,那么初始化如何工作?

时间:2019-01-09 11:47:32

标签: c++ arrays c++11

关于使用std::array初始化std::initializer_list数据成员有很多问题和答案,以及如何解决这是不可能的,因为没有std::array可用的构造函数。我想知道std::array的初始化如何工作?

拨打这样的电话在幕后会发生什么:

std::array<int, 4> a = {1,2,3,4};  // (1)

如果该参数不是std::initializer_list<int>,则该参数如何解释?

我试图通过查看libstdc++ source code并弄清楚_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)。

此外,如果我将std::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)...)

0 个答案:

没有答案