从int到vector的隐式转换?

时间:2013-05-07 20:25:39

标签: c++ visual-studio vector type-conversion explicit-constructor

vector<T>有一个构造函数,它取了向量的大小,据我所知它是 explicit ,这可以通过以下代码无法编译的事实证明

void f(std::vector<int> v);
int main()
{
    f(5);
}

我无法理解并要求您解释为什么以下代码编译

std::vector<std::vector<int>> graph(5, 5);

它不仅编译,它实际上将图形大小调整为5并将每个元素设置为五个零的向量,即与我通常编写的代码相同:

std::vector<std::vector<int>> graph(5, std::vector<int>(5));

如何?为什么呢?

编译器:MSVC10.0


好吧,好像,这是一个MSVC错误(还有一个)。如果有人可以在答案中详细说明错误(即总结复制的情况),我很乐意接受它

3 个答案:

答案 0 :(得分:7)

这不是一个真正的错误。问题是在第一段代码不能编译时允许第二段代码可能出错?

问题在于,当您执行以下操作时,您想要调用的构造函数似乎很明显:

std::vector<std::vector<int>> graph(5, 5);

编译器不太清楚。特别是有两个构造函数重载可以接受参数:

vector(size_type,const T& value = T());

template <typename InputIterator>
vector(InputIterator first, InputIterator last);

第一个需要将5转换为size_type(无符号),而第二个是完美匹配,因此这将是编译器选择的那个... < / p>

...但编译器要求第二次重载,如果推断的类型InputIterator是积分的,就好像它是一个调用:

vector(static_cast<size_type>(first),static_cast<T>(last))

C ++ 03标准有效强制要求第二个参数显式从原始类型int转换为目标类型std::vector<int>。由于转换是明确的,因此您会收到错误。

如果参数实际上不是输入迭代器,那么C ++ 11标准改变了使用SFINAE来禁用迭代器构造函数的措辞,因此在C ++ 11编译器中代码应该被拒绝(这可能是某些原因)声称这是一个错误。)

答案 1 :(得分:2)

对我来说,看起来它正在调用这个构造函数:

template <class InputIterator>
vector (InputIterator first, InputIterator last,
  const allocator_type& alloc = allocator_type());

我不确定explicit在哪里,因为构造函数需要多个参数。它不是从int自动转换为向量。

答案 2 :(得分:1)

这实际上是一个扩展,而不是一个错误。

被调用的构造函数是一个带有两个迭代器的构造函数(但实际上,签名将匹配同一类型的任何两个参数);然后它会调用两个迭代器实际为int时的特化,它使用value_type的值显式构造end并使用begin个副本填充向量。