To perform some recursive tasks locally, I use the following approach to create a fixed-point combinator:
#include <utility>
#include <list>
#include <memory>
#include <iostream>
int main()
{
struct tree
{
int payload;
std::list< tree > children = {};
};
std::size_t indent = 0;
const auto print = [&] (const auto & self, const tree & node) -> void
{
std::cout << std::string(indent, ' ') << node.payload << '\n';
++indent;
for (const tree & t : node.children) {
self(self, t);
}
--indent;
};
print(print, {1, {{2, {{8}}}, {3, {{5, {{7}}}, {6}}}, {4}}});
}
It works fine and prints:
1
2
8
3
5
7
6
4
But if I delete the explicitly specified result type -> void, then I get a compilation error (GCC 8):
prog.cc: when creating 'main () :: [with auto: 1 = main () ::]':
prog.cc24: 64: required from here
prog.cc:20:17: error: using 'main () :: [with auto: 1 = main () ::]' before outputting 'auto'
self(self, t);
(clang 7):
prog.cc:20:13: error: function 'operator () <(lambda at prog.cc:15:24)>' with the returned return type cannot be used until it is determined
self(self, t);
^
prog.cc:24:10: note: 'main()::( ):: operator() < (lambda at prog.cc:15:24) > '
print(print, {1, {{2, {{8}}}, {3, {{5, {{7}}}, {6}}}, {4}}});
^
prog.cc:15:24: note: 'operator() < (lambda at prog.cc:15:24) > '
const auto print = [&] (const auto & self, const tree & node)
^
1 .
? , , . "" self.