Fixed point combinator and explicit result type

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::list of incomplete type is allowed
    };
    std::size_t indent = 0;
    // indication of result type here is essential
    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.

+6
2

[dcl.spec.auto]:

- , . , , , , , return.

void , undeduced typeholder, .

, ,

print(print, {1, {{2, {{8}}}, {3, {{5, {{7}}}, {6}}}, {4}}});

self(self, t) print operator() ( " " ), .

+2

, (, ), , , , . , , , , . , .

+3

All Articles