2017-09-05 115 views
3

摺疊表達式似乎是將函數應用於元組的每個元素的好方法。但是,如果應用函數有副作用,那麼函數調用的順序可能是一個重要的問題。摺疊表達式的評估順序

考慮:

#include <iostream> 

template<typename... Ts> 
void printStuff(Ts... args) 
{ 
    (([](auto&& v) { std::cout << v << " "; })(args), ...); 
    std::cout << '\n'; 
} 

int main() 
{ 
    printStuff("hello", 42, 1.5f); 
    // expected output: hello 42 1.5 
} 

seems to work

但是,在這裏保證的lambda表達式的評估順序還是可以最終在輸出中翻轉值?如果我使用不同的操作員來一起鏈接命令,答案會改變嗎?

+3

您使用逗號運算符,該運算符已排序。 – Jarod42

回答

9

操作符的右側展開如下所示:... (arg0 op (arg1 op arg2))。所以,雖然這些人的幫助,但他們不保證任何有關各個元素的順序。

因此,這全部留給op。而comma operator(與逗號分隔函數參數不同),甚至是pre-C++ 17,都是一個很難的序列點。它確保從左到右的評估不會出現串擾。

如果您改爲使用+,則不會有序列保證。這取決於您使用的操作員。 C++ 17增加了幾個具有嚴格排序保證的運算符(例如,<<)。

+1

僅供參考:在C++ 17中爲我們提供了更嚴格的時序保證的建議是[P0145r3](https://wg21.link/P0145r3)。這也保證了重載逗號操作符不會消除順序保證。 – ComicSansMS

+0

OP正在使用正確的摺疊。 –

+0

@ T.C:你知道,你有完整的編輯權限。你可以自己修復它。 –