Pav*_*Dev 11 c++ language-lawyer
为了填充std::vector<struct_name>from std::cin,我通常写如下代码:
struct point{
int x, y;
};
int main()
{
std::size_t n;
std::cin>>n;
std::vector<point> vec(n);
for (auto& p:vec)
std::cin>>p.x>>p.y;
//...
}
Run Code Online (Sandbox Code Playgroud)
但是今天我发现了另一种使用默认构造函数的方法:
struct point{
int x, y;
point(){
std::cin>>x>>y;
}
};
int main()
{
std::size_t n;
std::cin>>n;
std::vector<point> vec(n);
//...
}
Run Code Online (Sandbox Code Playgroud)
问题:
我对根据 C++11(和更新的)标准的行为感兴趣
Bri*_*ian 13
不能保证元素按其索引的顺序进行初始化。在 C++11 中,请参阅 [vector.cons]/3:
效果:构造一个
vector具有n值初始化的元素。
这对排序没有任何说明,因此不能假设任何内容。该标准的后续版本中的措辞发生了变化,但似乎从未强加过任何顺序。
关于您的第一个问题,处理序列容器的C++20(但这也可以追溯到C++11)部分不承诺在向量本身内构造元素的顺序,只是将元素设置为某个特定值:vector
效果:
vector使用n默认插入的元素构造一个。
对那个(非常简短的)部分(a) 中的顺序一无所知。
但是你的方法有一个更大的问题,特别是我不认为你真的想cin在默认构造点变量的每种情况下都去。
例如,在某些情况下,您需要一个默认构造的临时变量,如果您的程序突然停止接受用户输入,它会被视为挂起,尤其是在没有向用户提示的情况下:-)
这让你的第二个问题没有实际意义,但是,假设你担心初始化向量元素的效率低下,然后用输入循环改变它们,我不会。没有构造函数的结构(即,只有几个int变量)不需要初始化它们(b),因此它们的向量可以进行分配并在那里停止。
(a)中的一些命令被在标准保证的,例如不同的构件的一类中的顺序,或一个阵列内的元件的顺序。然而,向量的元素都不是这些东西。
(b)这包括在C++20 10.9 Iniitialisation [class.init]:
当没有为(可能是 cv 限定的)类类型(或其数组)
()的对象指定初始值设定项时,或初始值设定项的形式为 时,对象将按照 中指定的方式进行初始化9.3。
和C++20 9.3 Initializers [dcl.init]:
默认初始化一个类型的对象
T意味着:
- 如果
T是(可能是 cv 限定的)类类型,则考虑构造函数。枚举适用的构造函数,并()通过重载决议选择最佳构造函数。如此选择的构造函数被调用,参数列表为空,以初始化对象。- 如果
T是数组类型,则每个元素都是默认初始化的。- 否则,不执行初始化。
对于没有显式定义或继承的构造函数的类型,这是第一个要点。在这种情况下,它使用隐式定义的构造函数,相当于没有主体和初始化列表的用户定义的构造函数。