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