2015-10-19 142 views
5

如果我有函數調用在這樣的循環狀態:函數調用for循環條件?

for (auto it = s.begin(); it != s.end(), ++it) {} 

叫在每次迭代?我希望是的。編譯器是否允許優化它呢?目前的編譯器是否足夠聰明以做到這一點?或者我更好地使用類似以下的東西:

for (auto it = s.begin(), auto end = s.end(); it != end; ++it) {} 

+0

當您使用C++ 11時,請考慮使用基於範圍的for循環來避免此問題。 –

+0

@NeilKirk在我的情況下不可用,我實際上需要迭代器來做有趣的事情。 – Paladin

+1

我個人使用第二種方法編寫循環,然後我不必擔心它。我不知道它在實踐中有多重要或不重要。 –

回答

4

是的,程序必須在每次迭代中調用第二個表達it != s.end()。我認爲編譯器可以在某些情況下優化它。

無論如何,不​​要編譯器的工作。如果它可以被優化,編譯器就有很大的機會做到這一點,並且無論如何這個調用沒有顯着的性能影響。

如果情況允許,你應該使用基於for循環的範圍:

for (auto& i : s) { 
    // instructions 
} 

這樣,編譯器有更多的機會來優化你的代碼,它是更容易閱讀。

如果你想了解一下編譯器可以優化多少東西的例子,看看這個! http://ridiculousfish.com/blog/posts/will-it-optimize.html

+0

我通常會使用它,但實際上我需要操縱迭代器,所以經典的foreach循環對我來說不起作用 – Paladin

+0

啊,然後使用循環的經典。但是再次,編譯器非常聰明。在這種情況下,不需要複雜的代碼。 –

+0

我編輯我的答案是更通用的,我只是添加了一個偉大的文章的鏈接。 –

6

for (auto it = s.begin(); it != s.end(), ++it) 

s.begin()只調用一次。
s.end()operator++()(對於++it)在循環的每次迭代中被調用。

編譯器允許優化它嗎?

根據編譯器,實現和優化級別,編譯器可以優化掉s.end()的調用。如果能優化掉operator++()的電話,我會感到驚訝。

當前的編譯器足夠聰明嗎?

無法回答。

還是我更好地使用類似以下內容:

for (auto it = s.begin(), auto end = s.end(); it != end; ++it) {} 

它不會傷害。但是,如果在循環中修改s,則可能會出現問題。如果s未在循環中修改,我會建議使用此方法。

1

是的,它在每次迭代中被正式調用。是的,目前的編譯器可能會內聯該函數,並且每次看到s.end()返回相同的值(指針?)。

除非分析顯示這是程序中的瓶頸(極不可能),否則不需要複雜的代碼。