Skip to content

Latest commit

 

History

History
138 lines (106 loc) · 3.06 KB

247.md

File metadata and controls

138 lines (106 loc) · 3.06 KB
Info

Example

struct foo {
  auto bar(bool b) { return b; }

  // deducing this
  auto baz(this foo const & self, bool b) { return not b; }
};

static_assert(foo{}.bar(true));
static_assert(not foo{}.baz(true));

static_assert(not foo{}.bar(false));
static_assert(foo{}.baz(false));

https://circle.godbolt.org/z/TMc63G5Tf

Puzzle

  • Can you implement sum which adds args... by using a recursive lambda with deduced this?
constexpr auto sum = [](...); // TODO

static_assert(0 == sum());
static_assert(1 == sum(1));
static_assert(3 == sum(1, 2));
static_assert(6 == sum(1, 2, 3));
static_assert(6 == sum(2, 3, 1));

https://circle.godbolt.org/z/j8a7oc8nT

Solutions

constexpr auto sum = [](this const auto& self, auto... args) {
  if constexpr (sizeof...(args) == 0) {
    return 0;
  } else {
    return [&](auto arg, auto... args) { return arg + self(args...); }(args...);
  }
};

https://circle.godbolt.org/z/Gf7PdP64G

constexpr auto sum = [](this auto self, auto ... args)
{
    auto peelArg = [&](auto arg, auto ...args) {
        return arg + self(args...);
    };

    if constexpr (sizeof...(args) == 0)
        return 0;
    else
        return peelArg(args...);
};

https://circle.godbolt.org/z/vnrTEnGcr

constexpr auto sum = [](this const auto& self, const auto&... args) {
    if constexpr(sizeof...(args) == 0) {
        return 0;
    } else {
        return [self](const auto& first_arg, const auto&... remaining_args) {
            return first_arg + self(remaining_args...);
        }(args...);
    }
};

https://circle.godbolt.org/z/7cz5WbTd3

constexpr auto sum = [](this auto & self, auto ... Is ){
    if constexpr ( (sizeof ...( Is) ) == 0 )
        return 0;
    else
        return [&]( auto I , auto ... Iss ) { return I + self.operator()( Iss ... ) ; }( Is...);
};

https://circle.godbolt.org/z/7d8acTPWE

constexpr auto sum = [] (this const auto &self, auto... args) {
    if constexpr (sizeof...(args) >= 1) {
        return [=] (auto first, auto... rest) {
            return first + self(rest...);
        }(args...);
    }

    return 0;
};

https://circle.godbolt.org/z/c4Pjb51cc

constexpr auto sum = [](this const auto& self, auto... args) {
    if constexpr (sizeof...(args) > 0) {
        return [self](const auto head, const auto... tail) {
            return head + self(tail...);
        }(args...);
    }
    return 0;
};

https://circle.godbolt.org/z/PzzEKs14q

constexpr auto sum = [](this auto const &self, auto ...args){
    if constexpr ( sizeof...(args) == 0 ){
        return 0;
    } else {
        return [=](const auto arg, auto ... rest_of_args){
            return arg + self(rest_of_args...);
        }(args...);
    }
};

https://circle.godbolt.org/z/zas389zWT