我在一些非常著名的C ++书籍中看到-
vector<int> ivec;
for (vector<int>::size_type i = 0; i != 10; ++i) {
ivec.push_back(i);
ivec.push_back(i); // duplicate copies of each number
}
我想知道为什么在这里使用vector<int>::size_type
。他们不是
将i
与向量的大小进行比较。目的是将10个int
插入
向量,所以int i = 0
是正确的做法,不是吗?
vector<int>::size_type
将是typedef
的{{1}},这将依次
是std::size_t
,但这里我们将unsinged int
存储在int
中。
请阐明我对vector
的理解。在上面的for循环中使用它是否公平?
答案 0 :(得分:4)
基本上,上面的代码在编译和完成预期工作的意义上是“好的”,就像其他人所说的那样。
当他们说要在向量中插入十个int
时,由于循环的格式确定,int
被保证为正数,因此unsigned int
只会转换进入int
。
但是,正如您所说,我不认为这是一种好习惯-大小类型与要插入的元素的类型无关-大小类型基本上始终是unsigned int
。显然,仅使用int
或value_type
可以使代码的意图更加清晰。
答案 1 :(得分:3)
我会说不,这段代码不正确,许多编译器会警告从size_t
到int
的隐式强制转换。
vector::size_type
/ size_t
应该始终用于向量索引,但是如果您有vector
的{{1}},则应该在其中插入int
正确的代码是:
int
答案 2 :(得分:0)
为避免隐式强制转换和编译器警告,您可以明确说明push_back
的内容:
vector<int> ivec;
for (vector<int>::size_type i = 0; i != 10; ++i) {
ivec.push_back(static_cast<int>(i));
ivec.push_back(static_cast<int>(i));
}
在此代码中使用size_type
和static_cast
似乎是人为的。在下面的示例(@AlanBirtles的示例的组合)中,它将更有意义:
vector<int> ivec(20);
for (vector<int>::size_type i = 0; i != 10; ++i) {
ivec[2 * i] = ivec[2 * i + 1] = static_cast<int>(i);
}
答案 3 :(得分:0)
是的,您的值类型为int
。
但这不是size_type
所说的。 size_type
是向量索引的类型。这是向量的 size 的类型(因此得名!)。
为此我们使用类型别名(由标准库提供),因为它在各个系统之间可能/将有所不同。它通常是一个size_t
,它本身是某些大的无符号类型的标准别名,尽管您通常无法预测可移植程序的类型。
这个特殊的例子令人困惑,因为书的作者确实使用大小类型填充向量值。这不一定是“错误的”:在0-9的范围内,它不会中断。编译器将按照通常的方式隐式转换整数。
但是它表达的意图不正确。
我想它曾经是这样的:
vector<int> v(5);
for (vector<int>::size_type i = 0; i < v.size(); i++)
v[i] = 42;
然后有人更改了循环主体(例如,i
现在用于值,而不是用于索引),而没有考虑过更改循环序言。
将i
设为int
会更加清晰和明显。
总体而言,我会考虑避免使用这些“知名书籍”,或者至少要检查它们的勘误表以查看发布后代码是否已进行了调整,因为那是C ++的一个很奇怪的例子。