【发布时间】:2011-10-08 22:15:38
【问题描述】:
取以下代码:
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++ 实现具有正确的行为,无论它采用哪条路径来实现它。
【问题讨论】:
-
10不是迭代器,我认为 VC++ 在这里是错误的,你得到正确的结果只是偶然。 -
我不认为这是机会。被调用的
_Construct函数具有签名void _Construct(_Iter _Count, _Iter _Val, _Int_iterator_tag),因此看起来像是有意的。这两个_Construct函数仅在构造函数中调用,也采用两个迭代器。 -
你得到什么编译错误?此外,您可能希望在结束
>之间添加一个空格(即std::vector<std::vector<int> > v(10, 10);而不是std::vector<std::vector<int>> v(10, 10);以避免混淆编译器。 -
错误:没有匹配函数调用'__cxx1998::vector
>::_M_fill_initialize(__cxx1998::vector >::size_type, int&)'跨度>
标签: c++ standards-compliance msvcrt libstdc++ c++-standard-library