从int到vector的隐式转换?

Arm*_*yan 8 c++ vector type-conversion explicit-constructor visual-studio

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

void f(std::vector<int> v);
int main()
{
    f(5);
}
Run Code Online (Sandbox Code Playgroud)

我无法理解并要求您解释的是以下代码编译的原因

std::vector<std::vector<int>> graph(5, 5);
Run Code Online (Sandbox Code Playgroud)

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

std::vector<std::vector<int>> graph(5, std::vector<int>(5));
Run Code Online (Sandbox Code Playgroud)

怎么样?为什么?

编译器:MSVC10.0


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

Dav*_*eas 7

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

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

std::vector<std::vector<int>> graph(5, 5);
Run Code Online (Sandbox Code Playgroud)

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

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

template <typename InputIterator>
vector(InputIterator first, InputIterator last);
Run Code Online (Sandbox Code Playgroud)

第一个需要转换5size_type(无符号),而第二个是完美匹配,所以这将是编译器选择的那个......

...但是编译器要求第二次重载,如果推导出的类型InputIterator是积分,则表现得像是调用:

vector(static_cast<size_type>(first),static_cast<T>(last))
Run Code Online (Sandbox Code Playgroud)

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

如果参数不是真正的输入迭代器,C++ 11标准改变措辞使用SFINAE来禁用迭代器构造函数,因此在C++ 11编译器中代码应该被拒绝(这可能是一些人声称这个的原因)成为一个错误).