Skip to content

Instantly share code, notes, and snippets.

@fosterbrereton
Created April 19, 2016 22:27
Show Gist options
  • Save fosterbrereton/4f3d00cedef3a79cf0b1d516db27eae5 to your computer and use it in GitHub Desktop.
Save fosterbrereton/4f3d00cedef3a79cf0b1d516db27eae5 to your computer and use it in GitHub Desktop.
How do I fix banana?
#include <iostream>
#include <typeinfo>
struct banana_t {
template <typename T>
explicit banana_t(const T& x) :
impl_m{new impl<T>(x)}
{ }
struct base_t {
template <typename T>
explicit base_t(const T&) : type_m(typeid(T)) { }
virtual ~base_t() { };
const std::type_info& type_m;
};
template <typename T>
struct impl : base_t {
explicit impl(const T& x) :
base_t(x),
x_m{x}
{ }
T x_m;
};
base_t* impl_m;
};
template <typename T>
T& cast(banana_t& banana) {
banana_t::impl<T>* impl = dynamic_cast<banana_t::impl<T>*>(banana.impl_m);
if (!impl) {
std::string error = std::string("Expected: ") +
banana.impl_m->type_m.name() +
"; got " +
typeid(T).name();
throw std::runtime_error(error);
}
return impl->x_m;
}
template <typename T>
void reassign(banana_t& banana, const T& x) {
cast<T>(banana) = x;
}
void test0() {
banana_t banana(42);
std::cout << cast<int>(banana) << '\n';
reassign(banana, 100);
std::cout << cast<int>(banana) << '\n';
}
void test1() {
std::shared_ptr<int> p(std::make_shared<int>(42));
banana_t banana(p);
std::cout << *cast<std::shared_ptr<int>>(banana) << '\n';
std::shared_ptr<const int> p2(std::make_shared<int>(100));
reassign(banana, p2);
std::cout << *cast<std::shared_ptr<int>>(banana) << '\n';
}
int main(int argc, const char * argv[]) try {
test0();
test1();
return 0;
} catch (const std::exception& error) {
std::cerr << "Fatal exception: " << error.what() << '\n';
} catch (...) {
std::cerr << "Unknown fatal exception\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment