请看下面的代码:
std::vector<std::vector<int>> v(10, 10);
这段代码在libstdc++下无法编译。然而,在使用Visual Studio的C++库时可以编译成功。我期望的行为是v
被填充了10个长度为10的向量,而这正是我在使用Visual Studio时得到的结果。
使用Visual Studio调用的构造函数是接受两个迭代器的构造函数。构造函数本身定义如下:
template<class _Iter>
vector(_Iter _First, _Iter _Last)
: _Mybase()
{ // construct from [_First, _Last)
_Construct(_First, _Last, _Iter_cat(_First));
}
有两个版本的模板函数
_Construct
。它们具有相同的签名,但一个从范围初始化向量,另一个使用从第二个参数复制构造的值类型的N个副本初始化向量。在这种情况下,模板参数仅对_Construct
的第二个版本有效。结果是
v
被填充了10个从值10复制构造的向量的副本。通过像这样构造它,将采取相同的代码路径,正如您需要使用libstdc++实现相同效果时所做的那样:std::vector<int> temp(10);
std::vector<std::vector<int>> v(10, temp);
哪种实现是正确的?这是libstdc++的错误还是Visual Studio的C++库的扩展?
编辑:澄清一下,我不是在问是否应该调用范围构造函数。我想知道哪个C++实现有正确的行为,无论它采取哪种方式来实现。
_Construct
函数具有签名void _Construct(_Iter _Count, _Iter _Val, _Int_iterator_tag)
,因此看起来它是有意的。这两个_Construct
函数仅从构造函数中调用,该构造函数接受两个迭代器。 - Collin Dauphinee>
之间添加一个空格(例如std::vector<std::vector<int> > v(10, 10);
而不是std::vector<std::vector<int>> v(10, 10);
),以避免让编译器产生困惑。 - John Carter