Skip to content

Latest commit

 

History

History
136 lines (104 loc) · 2.93 KB

324.md

File metadata and controls

136 lines (104 loc) · 2.93 KB
Info

Example

struct A {
    int a{};
};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};

int main() {
    D d{};
    d.a = {};  // without virtual -> request for member 'a' is ambiguous
}

https://godbolt.org/z/qG46qW7TG

Puzzle

template <class... Ts>
struct interface;  // TODO

template <auto... Vs>
struct implementation final;  // TODO

#include <https://raw.githubusercontent.com/boost-ext/ut/v1.1.9/include/boost/ut.hpp>

int main() {
    using namespace boost::ut;

    "virtual type_list interface empty"_test = [] {
        auto impl = implementation<>{};
        const interface<>& i = impl;
    };

    "virtual type_list interface single"_test = [] {
        auto impl = implementation<int{42}>{};
        const interface<int>& i = impl;
        expect(42 == i.on(int{}));
    };

    "virtual type_list interface multi"_test = [] {
        auto impl = implementation<int{4}, double{2.}, float{42.f}>{};
        const interface<int, double, float>& i = impl;
        expect(4 == i.on(int{}));
        expect(2. == i.on(double{}));
        expect(42.f == i.on(float{}));
    };
}

https://godbolt.org/z/qs4K917ac

Solutions

template <class... Ts>
struct interface {
   public:
    template <class T>
    const T& on(T) const {
        return std::get<T>(vs);
    }

   protected:
    constexpr explicit interface(auto&&... args) : vs(args...) {}

   private:
    std::tuple<Ts...> vs;
};

template <auto... Vs>
struct implementation final : interface<decltype(Vs)...> {
    constexpr explicit implementation() : interface<decltype(Vs)...>(Vs...) {}
};

https://godbolt.org/z/csrTfEcnP

template <class... Ts>
struct interface : virtual interface<Ts>... {
    using interface<Ts>::on...;
};

template <class T>
struct interface<T> {
    virtual T on(T) const = 0;
    virtual ~interface() noexcept = default;
};

template <auto... Vs>
struct implementation : interface<decltype(Vs)...>, implementation<Vs>... {};

template <auto V>
struct implementation<V> : virtual interface<decltype(V)> {
    using T = decltype(V);
    T on(T) const { return V; }
};

https://godbolt.org/z/vo18fjTja

template <class... Ts>
struct interface : virtual interface<Ts>... {
    using interface<Ts>::on...;
};

template <class T>
struct interface<T> {
    virtual T on(T) const = 0;
};

template <auto... Vs>
struct implementation final : implementation<Vs>...,
                              interface<decltype(Vs)...> {};

template <auto V>
struct implementation<V> : virtual interface<decltype(V)> {
    using T = decltype(V);
    T on(T) const override { return V; }
};

https://godbolt.org/z/bfxPc3KE8