Skip to content

Latest commit

 

History

History
215 lines (167 loc) · 3.83 KB

248.md

File metadata and controls

215 lines (167 loc) · 3.83 KB
Info

Example

template <class T>
struct interface {
    auto get() const {
        return static_cast<const T*>(this)->get_impl();
    }
};

struct impl1 : interface<impl1> {
    auto get_impl() const { return 1; }
};

struct impl2 : interface<impl2> {
    auto get_impl() const { return 2; }
};

template<class T>
auto get(const interface<T>& b) {
  return b.get();
}

int main() {
    return get(impl1{}) + get(impl2{}); // returns 3
}

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

Puzzle

  • Can you implement the CRTP example with Deducing this instead?
struct interface;             // TODO
template<auto N> struct impl; // TODO
auto get(...);                // TODO

static_assert(0 == get(impl<0>{}));
static_assert(1 == get(impl<1>{}));
static_assert(3 == get(impl<1>{}) + get(impl<2>{}));

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

Solutions

struct interface {
  auto get(this const auto& impl) {
    return impl.get_impl();
  }
};

template<auto N> struct impl : interface {
  auto get_impl() const { return N; }
};

auto get(const /*std::derived_from<interface>*/ auto& iface) {
  return iface.get();
}

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

class interface {
public:
    template<typename T>
    [[nodiscard]] constexpr auto get(this const T&) {
        return T::get_impl();
    }
};

template<auto N>
class impl : interface {
private:
    [[nodiscard]] static constexpr auto get_impl() {
        return N;
    }
};

[[nodiscard]] constexpr auto get(const auto &object) {
    return object.get();
}

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

struct interface {
  auto get(this const auto& impl) requires requires { impl.get_impl(); } {
    return impl.get_impl();
  }
};

template<class T> concept Interface = requires (T t) { t.get(); };

template<auto N> struct impl : interface {
  auto get_impl() const { return N; }
};

auto get(const Interface auto& i) {
  return i.get();
}

https://circle.godbolt.org/z/5PjsW7Tvx

struct interface {
    constexpr auto get(this const auto& self) {
        return decltype(self)::value;
    }
};

template<auto N> struct impl : interface {
    static constexpr auto value = N;
};

auto get(const auto& i) {
    return i.get();
}

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

struct interface
{
    template <typename Self>
    auto get(this Self && self)
    {
        return std::forward<Self>(self).get_impl();
    }
};

template<auto N>
struct impl : interface
{
    auto get_impl() const
    {
        return N;
    }
};

template <typename T>
auto get(T && val) {
    return std::forward<T>(val).get();
}

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

struct interface{
    auto get( this auto &&  self )
    {
        return self();
    }
};

template<auto N> struct impl:public interface {
    auto operator()()
    {
        return N;
    }
};

auto get(auto && f){
    return f.get();
}

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

struct interface {
    auto get(this auto const &self) {
        return self.get_impl();
    }
};

template<auto N> struct impl : interface {
    auto get_impl() const { return N; }
};

auto get(const auto &self) { return self.get(); }

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

struct interface {
    auto get(this auto const &self) {
        return self.get_impl();
    }
};

template<auto N> struct impl : interface {
    auto get_impl() const { return N; }
};

auto get(const auto &self) { return self.get(); }

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