2017-09-05 1 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

ここで保証されているラムダの評価の順番ですか、値が出力されてしまうことになりますか?コマンドを連鎖させるために別の演算子を使用した場合、答えは変わりますか?

+3

シーケンスされたコンマ演算子を使用します。 – Jarod42

答えて

9

オペレータを右に折ると、次のように展開されます。... (arg0 op (arg1 op arg2))したがって、括弧は助けになりますが、個々の要素の順序について何も保証するものではありません。

したがって、すべて最大でopです。 comma operator(関数の引数を区切るカンマとは別のもの)は、プレC++ 17でもハードシーケンスポイントです。それはクロストークなしで左から右への評価を保証します。

代わりに+を使用した場合は、シーケンス保証はありません。したがって、使用する演算子によって異なります。 C++ 17では、厳密なシーケンス保証がある演算子をいくつか追加しました(たとえば、<<)。

+1

参考:C++ 17でより厳密なシーケンス保証が得られた提案は[P0145r3](https://wg21.link/P0145r3)です。これは、コンマ演算子のオーバーロードがシーケンシングの保証を削除しないことを保証します。 – ComicSansMS

+0

OPは右折を使用しています。 –

+0

@ T.C .:あなたが知っているあなたには完全な編集権があります。あなたは自分でそれを修正することができました。 –