从int隐式转换为vector? [英] Implicit conversion from int to vector?
问题描述
vector<T>
的构造函数采用矢量的大小,据我所知 explicit ,可以通过以下代码无法编译的事实来证明 >
vector<T>
has a constructor that takes the size of the vector, and as far as I know it is explicit, which can be proved by the fact that the following code fails to compile
void f(std::vector<int> v);
int main()
{
f(5);
}
我无法理解,请您解释一下为什么下面的代码会编译
What I cannot understand and am asking you to explain is why the following code compiles
std::vector<std::vector<int>> graph(5, 5);
它不仅可以编译,而且实际上将图形的大小调整为5,并将每个元素设置为具有五个零的向量,即,与我通常编写的代码相同:
Not only does it compile, it actually resizes graph to 5 and sets each element to a vector of five zeros, i.e. does the same as would the code I would normally write:
std::vector<std::vector<int>> graph(5, std::vector<int>(5));
如何?为什么?
编译器:MSVC10.0
Compiler: MSVC10.0
好的,似乎是MSVC错误(还有另一个).如果有人可以详细说明答案中的错误(即总结复制该错误的情况),我会很乐意接受
OK, seems it's an MSVC bug (yet another one). If someone can elaborate on the bug in an answer (i.e. summarize the cases where it is reproduced) I would gladly accept it
推荐答案
这并不是一个错误.问题是,如果第二段代码无法编译,那么允许第二段代码会出错吗?
It is not really a bug. The question is what could go wrong to allow the second piece of code while the first does not compile?
问题是,虽然您似乎很明显在执行操作时要调用什么构造函数:
The issue is that while it seems obvious to you what constructor you want to call when you do:
std::vector<std::vector<int>> graph(5, 5);
对于编译器来说还不是很清楚.特别是,有两个可能会接受参数的构造函数重载:
it is not so clear for the compiler. In particular there are two constructor overloads that can potentially accept the arguments:
vector(size_type,const T& value = T());
template <typename InputIterator>
vector(InputIterator first, InputIterator last);
第一个需要将5
转换为size_type
(无符号),而第二个则是完美匹配,因此将由编译器选择...
The first one requires the conversion of 5
to size_type
(which is unsigned), while the second is a perfect match, so that will be the one picked up by the compiler...
...但是如果推导的类型InputIterator
是整数,则编译器要求第二次重载的行为就好像是对以下命令的调用:
... but the compiler requires that the second overload, if the deduced type InputIterator
is integral behaves as if it was a call to:
vector(static_cast<size_type>(first),static_cast<T>(last))
C ++ 03标准有效地要求将第二个参数明确地从原始类型int
转换为目标类型std::vector<int>
.由于转换是显式的,因此会出现错误.
What the C++03 standard effectively mandates is that the second argument is explicitly converted from the original type int
to the destination type std::vector<int>
. Because the conversion is explicit you get the error.
如果参数不是真正的输入迭代器,则C ++ 11标准将措辞更改为使用SFINAE禁用迭代器构造函数,因此在C ++ 11编译器中应拒绝代码(这可能是某些原因的原因)声称这是一个错误).
The C++11 standard changes the wording to use SFINAE to disable the iterator constructor if the argument is not really an input iterator, so in a C++11 compiler the code should be rejected (which is probably the reason some have claimed this to be a bug).
这篇关于从int隐式转换为vector?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!