std :: vector构造函数行为

时间:2011-10-08 22:15:39

标签: c++ standards-compliance msvcrt libstdc++ c++-standard-library

请使用以下代码:

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 ++实现具有正确的行为,无论实现它的路径是什么。

2 个答案:

答案 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 ++中的一个错误。