我通常会和其他人讨论,如果container.end()和container.size()函数是内联的,我就无法确认这种行为。例如,如果我们有这样的For循环:
for (vector<int>::iterator it=v.begin(); it!=v.end(); ++it) {
//...
}
for (size_t k=0; k < v.size(); ++k) {
//...
}在上述情况下,会重复调用v.end()和v.size()函数吗?
中的行为
发布于 2011-04-11 02:57:38
根据定义,所有模板函数都是内联函数。编译器可能会选择使它们成为可调用的函数,特别是当它是调试模式编译时,但是最有可能的结果是代码内联。
可以但不太可能自动创建临时变量。编译器如何确定v.end()或v.size()返回值是否会受到循环中的代码的影响?我怀疑大多数人都不费事,尽管我也没有任何证据。
发布于 2011-07-02 18:01:11
即使函数是内联的,如果嵌套代码足够大/复杂,也不能指望编译器正确地优化循环。这是因为在语义上,您可能不会期望end()值在循环的每一次迭代中都会发生变化,因此应该只计算一次。但是,编译器可能无法根据混叠考虑和优化器中的其他“放弃”条件来提供这种保证。如果--就像其他海报一样--你预先计算了end()并将它存储在一个变量中,编译器就不会感到困惑。
例如:
typedef std::vector<int> intvec;
intvec v = external_function();
for (intvec::const_iterator vi = v.begin(); vi != v.end(); ++vi) {
call_external_function(v, *vi);
}从编译器的角度来看,call_external_function()很容易改变向量的大小。如果您知道这是不可能发生的,您应该这样告诉编译器:
for (intvec::const_iterator vi = v.begin(), ve = v.end(); vi != ve; ++vi) {
call_external_function(v, *vi);
}发布于 2011-04-11 03:43:13
即使模板函数是内联的,也很难说编译器将提供我们所需要的相同程度的优化。人们可以使用以下技术。
将v.end()存储在临时vEnd中
for(vector<TYPE>::iterator it = v.begin(), vEnd = v.end(); it != vEnd; it++) {}反向执行循环:
for (size_t k = v.size() - 1; k != (size_t)(-1) ; --k) { }https://stackoverflow.com/questions/5615496
复制相似问题