请使用以下代码:
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 ++实现具有正确的行为,无论实现它的路径是什么。
答案 0 :(得分:3)
std::vector<std::vector<int>> v(10, 10);
这不应该编译,因为向量的单个参数构造函数是显式的。
C ++ 03:
explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator());
C ++ 11:
explicit vector(size_type n);
这意味着像10这样的数字不能隐含地变成大小为10的向量。
答案 1 :(得分:0)
我期望的行为是v填充了10个大小为10的向量
GCC / libstdc ++ 4.1.2正是如此。被调用的_Construct
是
void std::_Construct<std::vector<int>, int>(std::vector<int>*, int const&)
(省略分配器)。我无法告诉你标准对此有何看法,但我的预感是,这是旧版GCC / libstdc ++中的一个错误。