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));
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));
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...);
}
};
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...);
};
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...);
}
};
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...);
};
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;
};
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;
};
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...);
}
};