繁体   English   中英

C ++:初始化(新)不同初始大小的向量数组

[英]C++ : initialize(new) an array of vector of different initial size

为了帮助您理解这一点,我提供了我的代码:(main.cpp),仅涉及一个文件。

#include <iostream>
#include <vector>
using namespace std;
class test{
public : 
    int member {0};
    void fun(){cout << "member is " << member << endl;}
    test(){}
    //test(int param) : member(param){} //this line is commented.
};

int main()
{
    vector<test> *vp = new vector<test>[2] {{10},{20}};
    //vector<test> array[2] {{10},{20}};//this won't work either.
    cout << "size of vp[0] is " << vp[0].size() << endl;
    cout << "size of vp[1] is " << vp[1].size() << endl;
    return 0;
}

我打算将vp[0]初始化为10,将vp[1]初始化为20 但是,当我在mac使用g++ -std=c++11 main.cpp -o main编译时,它抱怨:

main.cpp:14:45: error: chosen constructor is explicit in copy-initialization
    vector<test> *vp = new vector<test>[2] {{10},{20}};
                                            ^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:517:14: note: 
      constructor declared here
    explicit vector(size_type __n);
             ^
main.cpp:14:50: error: chosen constructor is explicit in copy-initialization
    vector<test> *vp = new vector<test>[2] {{10},{20}};
                                                 ^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:517:14: note: 
      constructor declared here
    explicit vector(size_type __n);
         ^

在CentOS Linux中使用相同的命令,我得到了

main.cpp: In function ‘int main()’:
main.cpp:14:54: error: converting to ‘std::vector<test>’ from initializer list would use explicit constructor ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = test; _Alloc = std::allocator<test>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<test>]’
     vector<test> *vp = new vector<test>[2] {{10},{20}};
                                                      ^
main.cpp:14:54: error: converting to ‘std::vector<test>’ from initializer list would use explicit constructor ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = test; _Alloc = std::allocator<test>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<test>]’

这里发生了什么? 为什么与关键字explicit有任何关系? 我知道vector有几个构造函数(例如带有initializer-list类型参数的构造函数)。 如果我初始化矢量,例如vector<test> temp {10} ,则将矢量初始化为大小10,而没有任何explicit顾虑。 我不知道vector<test> array[2] {{10},{20}}里面隐藏的东西是什么引起了我的错误。

有趣的是,如果我为类test提供了一个带有一个参数的构造函数(只需在代码中取消注释该行),则编译器根本不会抱怨。 但是更改了vector<test> array[2] {{10},{20}}的含义,以使用分别用1020初始化的2个test类型对象来初始化vector array[0] 但是我稍后尝试的语法vector<test> array[2] {10,20}再次出错。

我不知道这里发生了什么,完全迷路了。 初始化列表类型的{10,20}也不也是吗?

如果您能解释这里发生的事情以及如何初始化不同大小的向量数组(请不要使用绕过的方式),我将非常感激。 我想知道语法的确切含义。

首先,在直接初始化中允许使用explicit构造函数,但不能进行复制初始化。

然后,在汇总初始化中

(强调我的)

从类定义中数组下标/外观的顺序开始,每个direct public base, (since C++17)数组元素或非静态类成员都从初始化程序列表的相应子句中进行复制初始化。

这意味着对于new vector<test>[2] {{10},{20}}; {10}{20}用于复制初始化 vector<test>元素; 那么不考虑explicit构造函数。

如果我初始化矢量,例如vector<test> temp {10} ,则将矢量初始化为大小10,而没有任何explicit顾虑。

由于直接初始化中允许使用explicit构造函数

直接初始化比复制初始化更宽松:复制初始化仅考虑非显式构造函数和非显式用户定义的转换函数,而直接初始化则考虑所有构造函数和所有用户定义的转换函数。

出于同样的原因, new vector<test>[2] {std::vector<test>{10},std::vector<test>{20}}; 也可以。

顺便说一句:

如果我为类test提供一个带有一个参数的构造函数(只需在代码中取消注释该行),则编译器完全不会抱怨。

如果提供了可用于将int隐式转换为test的构造函数,则可以使用{10}构造std::initializer_list<test> ,然后使用std::vector<test>的构造函数将std::initializer_list<test>由于始终首选使用std::initializer_list<test> 顺便说一句,如果您explicit指定test的构造函数,则代码也将失败。

您正在使用以下代码初始化vector<test>对象: vector<test> array[2] {{10},{20}} 您得到的错误是通过使用vector::vector(size_t count) explicit 构造函数引起的。 vector构造函数将构造count默认构造的test对象。
因此,例如,如果未将其定义为explicit ,则最终将得到包含10个默认构造的test对象的array[0]和包含20个默认构造的test对象的array[1] 如果您打算这样做,则必须显式构造vector对象:

vector<test> foo[] = { vector<test>{ 10 }, vector<test>{ 20 } }

您确实想将测试对象构造到vector因此这种eplicit实际上是在保护您免于意外结束分配eplicit vector的情况。

当您添加test:test(int param)构造函数{{10},{20}}仍然无法使用explicit vector构造函数。 但这现在可以视为vector[0] 列表初始化 但是与完成操作类似: int array[2] = {42}第二个元素将被初始化为零; 因此,在这种情况下,您的第二个 vector也将未初始化。

暂无
暂无

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

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