Created
April 19, 2016 22:27
-
-
Save fosterbrereton/4f3d00cedef3a79cf0b1d516db27eae5 to your computer and use it in GitHub Desktop.
How do I fix banana?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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