fork(1) download
  1. #include <iostream>
  2. #include <vector>
  3. #include <memory>
  4. #include <typeinfo>
  5.  
  6. class Any {
  7. struct Base {
  8. virtual ~Base () {}
  9. virtual std::ostream & output (std::ostream &) const = 0;
  10. };
  11. template <typename T>
  12. struct Impl : Base {
  13. T value_;
  14. explicit Impl (T x) : value_(x) {}
  15. operator T () const { return value_; }
  16. std::ostream & output (std::ostream &os) const { return os << value_; }
  17. };
  18. std::shared_ptr<const Base> base_ptr_;
  19. public:
  20. Any () : base_ptr_() {}
  21. template <typename T> Any (T x) : base_ptr_(new Impl<T>(x)) {}
  22. template <typename T> operator T () const {
  23. return dynamic_cast<const Impl<T> &>(*base_ptr_.get());
  24. }
  25. friend std::ostream & operator << (std::ostream &os, const Any &a) {
  26. return a.base_ptr_->output(os);
  27. }
  28. };
  29.  
  30. int main () {
  31. std::vector<Any> v;
  32.  
  33. // insert heterogeneous data
  34. v.push_back(1);
  35. v.push_back("two");
  36. v.push_back(3.14F);
  37. v.push_back('4');
  38.  
  39. // demonstrate printing
  40. for (auto i = v.begin(); i != v.end(); ++i) {
  41. std::cout << *i << std::endl;
  42. }
  43.  
  44. // demonstrate type introspection
  45. for (auto i = v.begin(); i != v.end(); ++i) {
  46. try { static_cast<int>(*i); std::cout << *i << " is int\n"; }
  47. catch (std::bad_cast) {}
  48. try { static_cast<const char *>(*i); std::cout << *i << " is c_str\n"; }
  49. catch (std::bad_cast) {}
  50. try { static_cast<float>(*i); std::cout << *i << " is float\n"; }
  51. catch (std::bad_cast) {}
  52. try { static_cast<char>(*i); std::cout << *i << " is char\n"; }
  53. catch (std::bad_cast) {}
  54. }
  55. }
Success #stdin #stdout 0s 3480KB
stdin
Standard input is empty
stdout
1
two
3.14
4
1 is int
two is c_str
3.14 is float
4 is char