两者在C++形式上是否有区别
Is there difference between two for form in C++?
vector<int> a;
1.
for(vector<int>::iterator it = a.begin(); it != a.end(); ++it)
阿拉伯数字。
vector<int>::iterator end = a.end();
for(vector<int>::iterator it = a.begin(); it != end; ++it)
哪个更有效率?还是相同?
最初的批评:
1/典型教程示例
for(vector<int>::iterator it = a.begin(); it != a.end(); ++it)
没有魔法,但它提出了一个问题:a
在循环中是否曾经修改过结束边界可能会变化?
2/改进
vector<int>::iterator end = a.end();
for(vector<int>::iterator it = a.begin(); it != end; ++it)
a.end()
似乎只执行一次。然而,由于end
不是const
,它可以在循环内被修改。
此外,它还在外部作用域中引入了end
标识符,从而污染了它。
因此,性能有潜在的提高,但清晰度不高。此外,它要啰嗦得多。
我会提出其他几种方法:
3/最佳手册
for(vector<int>::iterator it = a.begin(), end = a.end(); it != end; ++it)
结合了v1
(相当简洁,无外部范围污染(和v2
(性能(的优点,但目前尚不清楚end
是否在环体内进行了修改。
4/升压驱动
BOOST_FOREACH(int& i, a)
甚至比v1
更简洁,一目了然,没有外部范围泄漏,并保证完全迭代(无法修改边界(。
不幸:
- 变量类型中的逗号存在问题(因为它依赖于预处理器(
- 编译时错误是完全神秘的(因为它依赖于预处理器(
注意:从理论上讲,人们可以在这里提出std::foreach
算法的情况,但老实说......在外部定义谓词涉及太多精力,并且会破坏代码局部性。
5/C++11 范围声明
for (int& i: a)
所有优点:
- 极其简洁
- 与最佳C++手写循环一样高性能
- 保证完整迭代,不问任何问题
而且没有问题(范围泄漏,预处理器魔术(。
就个人而言,我尽可能使用C++11范围(爱好项目(,否则BOOST_FOREACH
(在工作中(。
我避免像瘟疫一样修改我正在迭代的容器,当我需要过滤/删除元素时,我更喜欢依赖 STL 算法......否则很容易弄乱边界条件和迭代器失效。
2nd 效率更高,因为它只需要创建一次结束迭代器。
智能编译器可能会将第一个优化为第二个,但不能保证会发生这种情况。
这实际上是一个有点复杂的优化,因为编译器需要 100% 确定任何后续对 end(( 的调用都不会产生额外的影响或返回任何不同的东西。 基本上,它需要知道至少在循环中,end(( 总是返回这样的东西,即 end(( == 之前对 end(( 的调用。 编译器是否执行该优化无法保证。
第二种方式显然更好,因为它只调用 a.end(( 一次。本质上,如果您的树中有 N 个节点,则可以将 N 个调用保存到 a.end((。
我认为第一个 for 循环更确定。如果您在 for 循环中插入/擦除元素,则您定义的end
迭代器将失效。例如:
vector<int>::iterator mend = int_vec.end(), mbegin = int_vec.begin();
while(mbegin != mend)
{
cout << *mbegin << " ";
int_vec.erase(mbegin);
// mbegin is automatically invalidated
// execution of this program causes bizarre runtime_error !
// never try this at home !
}
上面代码的一个更安全的版本可能是这样的:
vector<int>::iterator mend = int_vec.end(), mbegin = int_vec.begin();
while(mbegin != mend)
{
cout << *mbegin << " ";
int_vec.erase(mbegin);
mbegin = int_vec.begin(); // ok, mbegin updated.
}
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 关于std::move的使用,是否有编译警告
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 在类内和类外的定义处执行类转发声明是否有区别
- 使用 std::move 将参数传递给函数,如果该参数声明为按值传递或使用移动操作数 &&,是否有区别?
- 在if条件下,右或左改变值的相等性检查是否有任何区别
- c++ 类中的静态常量变量和常量变量在存储方面是否有区别
- 这些编译器之间是否有任何区别
- 将全局声明为类声明语句的一部分与使用单独的语句声明全局之间是否有区别
- GCC 警告未使用的静态函数,但不警告静态内联:是否有实际区别?
- vector.size()= 0和vector.empty()之间是否有区别
- 显式运算符 = 调用和 = 运算符之间是否有区别
- 忽略内存消耗,使用“int”或“char”是否有区别
- 对于数据成员,如果包含对象已在动态内存中,则动态分配此变量(或不动态分配)之间是否有任何区别
- boost::function 和 std::tr1::function 之间是否有重要的区别需要了解
- 使用相等运算符或使用大括号为变量赋值是否有区别
- 具有公共成员而没有构造函数的结构和类之间的编译器是否有区别
- 将 delete 作为运算符或函数调用是否有任何区别
- 两者在C++形式上是否有区别
- 类中是否包含空的destcurator有区别吗