2

I came across this question, where the answer describes nice detail about how can the generic lambda functions be used to replace the std::function technique and how to rewire the stop condition to enable the return type deduction.

Based on the above I created the following working example:

#include <cstdio>

void printSeq(unsigned start) {
    auto recursion = [](auto&& self, const char* format, unsigned current) {
        printf(format, current);
        if(!current)
            return static_cast<void>(printf("\n"));
        else
            self(self, ", %u", current - 1);
    };

    recursion(recursion, "%u", start);
}

int main() {
    return (printSeq(15), 0);
}

My question is that what's the advantage using auto&& over the auto& in this case? Should I use the std::move here?

Akira
  • 4,385
  • 3
  • 24
  • 46
  • 1
    One thing to note is that since `recursion` doesn't capture anything, it's just a trivial object, so there will be no benefit from using `std::move`. – Justin Jul 09 '17 at 20:17

1 Answers1

3

auto& is lvalue only.

This matters little until you refactor and replace the lvalue recursive object with a temporary proxy memoizer, for example.

auto&& is harmless, and means "I do not mind if this is a temprary or whatever, just don't make a copy", which expresses meaning well here. auto& states "No temporaries allowed!" Sometimes you want to exclude temporaries when making a reference, but it is rare.

auto const&, auto and auto&& should be your bread and butter.

Only use auto& if your operation is explicitly about writing and you are ok with excluding proxy references.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524