[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
79 lines (56 loc) · 1.83 KB

345.md

File metadata and controls

79 lines (56 loc) · 1.83 KB
Info

Example

struct foo{};
constexpr auto f1 = foo{};
constexpr auto ptr = static_cast<const void*>(&f1);
constexpr auto f2 = static_cast<const foo*>(ptr); // okay in C++26

https://godbolt.org/z/noWqb4d5K

Puzzle

  • Can you implement constexpr type-erasure Animal_View?
struct Sheep {
    constexpr std::string_view speak() const noexcept { return "Baaaaaa"; }
};

struct Cow {
    constexpr std::string_view speak() const noexcept { return "Mooo"; }
};

// TODO Animal_View

std::string_view do_speak(Animal_View av) { return av.speak(); }

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

    "constexpr cast from void*"_test = [] {
        should("say Mooo for cow") = [] {
            constexpr Cow cow;
            auto result = do_speak(cow);
            expect(std::string_view{"Mooo"} == result);
        };

        should("say Baaaaaa for sheep") = [] {
            constexpr Sheep sheep;
            auto result = do_speak(sheep);
            expect(std::string_view{"Baaaaaa"} == result);
        };
    };
}

https://godbolt.org/z/aonE3dvcs

Solutions

struct Animal_View {
    const void *animal;
    std::string_view (*speak_func)(const void *animal);

    template <class Animal>
    Animal_View(const Animal &animal)
        : animal(&animal), speak_func([](const void *animal) {
              return static_cast<const Animal *>(animal)->speak();
          }) {}

    constexpr std::string_view speak() { return speak_func(animal); }
};

https://godbolt.org/z/fq6Y8snW5 https://godbolt.org/z/TfxzvTGYT