从int隐式转换为vector? [英] Implicit conversion from int to vector?

查看:340
本文介绍了从int隐式转换为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆