質問: 27; std::cout << "collatz_count1: " << collatz_count1(i) << std::endl; std::cout << "collatz_count2: " << collatz_count2(i) << std::endl; std::cout << "collatz_count3: " << collatz_count3(i) << std::endl; std::cout << "collatz_count4: " << collatz_count4(i) << std::endl; return 0; } ``` `collatz_count1`と`collatz_count2`はうまく動きます(`collatz_count1`はC++11でも)が、`collatz_count3`と`collatz_count4`はコンパイルエラーになります。`f`の型を`decltype(auto)`にコンパイルエラーになります。 ### 何が問題なのか? もっと汎用的にするため、ラムダ式の仮引数を`(auto n)`のようにした場合、`collatz_count1`のような書き方はできなくなると思っています。なぜなら`std::function`みたいな型をどのようにも書けないからです(かといって`std::function`と書いてしまうと、せっかくの`auto`が`int`に確定してしまいます)。となると上の`collatz_count3`のような書き方で動いて欲しいのですが、`f`の型が確定していないためキャプチャできないとエラーになります。これは`collatz_count4`も同じで、同じエラーとなります。そこで、`collatz_count2`のように、キャプチャではなく引数で渡せばうまく動きますが、簡潔とは言い難いです。 つまり、何がしたいかというと、 * ラムダ式の仮引数の型は`auto`にしてテンプレートのように使いたい。 * しかし、その場合の再帰はキャプチャでは実現できなくなるのをなんとかしたい。 なんとか方法はないのでしょうか?それとも現在のC++14の仕様では`collatz_count2`のように書くしかないのでしょうか? ### 検証環境 OS: macOS 10.12.1 GCC: Homebrew gcc 6.2.0 Clang: Apple LLVM version 8.0.0 (clang-800.0.42.1) `-std=c++14`付きでコンパイルしています。 ### 参考文献 C++ : ラムダ式のみでの再帰文 - Qiita C++プログラマ キャスブログ ラムダ式で再帰関数 - C++と色々 c++ - Recursive lambda functions in C++11 - Stack Overflow
回答: こんにちは。 近しい話題がnamed lambdaが必要な理由にありました。 > > autoは使えない。なぜなら、autoの名前は、その初期化式の中では、使えないからだ。 > > > だそうです。 そして、named lamdaを使えばできるとか。N2511で提案されてます。規格に入る見込みは分かりませんが。