fork download
  1. #include <boost/type_traits.hpp> // or <type_traits> for TR1
  2. #include <iostream>
  3.  
  4. struct edge {};
  5. struct weighted_edge : edge { virtual double get_weight() const { return 3.14; } };
  6. struct derived_edge : weighted_edge { virtual double get_weight() const { return 42; } };
  7.  
  8. template <typename E, bool is_weighted>
  9. struct edge_weight_impl;
  10.  
  11. template <typename E>
  12. struct edge_weight_impl<E, false>
  13. {
  14. typedef int result_type;
  15. int operator()(const E& e) const { return 1; }
  16. };
  17.  
  18. template <typename E>
  19. struct edge_weight_impl<E, true>
  20. {
  21. // typedef decltype(E().weight()) result_type; // c++0x
  22. typedef double result_type;
  23.  
  24. result_type operator()(const E& e) const
  25. {
  26. return e.get_weight();
  27. }
  28. };
  29.  
  30. template <typename E>
  31. typename edge_weight_impl<E, boost::is_base_of<weighted_edge, E>::value>::result_type
  32. get_weight(const E& e)
  33. {
  34. return edge_weight_impl<E, boost::is_base_of<weighted_edge, E>::value>()(e);
  35. }
  36.  
  37. int main()
  38. {
  39. edge e;
  40. weighted_edge we;
  41. derived_edge de;
  42.  
  43. std::cout << "--- static polymorphism" << std::endl;
  44. std::cout << "edge:\t" << get_weight(e) << std::endl;
  45. std::cout << "weighted_edge:\t" << get_weight(we) << std::endl;
  46. std::cout << "derived_edge:\t" << get_weight(de) << std::endl;
  47. // use some additional enable_if to get rid of this:
  48. std::cout << "bogus:\t" << get_weight("bogus") << std::endl;
  49.  
  50. std::cout << "\n--- runtime polymorphism" << std::endl;
  51.  
  52. edge* ep = &e;
  53. std::cout << "edge:\t" << get_weight(*ep) << std::endl;
  54. weighted_edge* wep = &we;
  55. std::cout << "weighted_edge:\t" << get_weight(*wep) << std::endl;
  56. wep = &de;
  57. std::cout << "bogus:\t" << get_weight(*wep) << std::endl;
  58.  
  59. }
  60.  
Success #stdin #stdout 0s 2724KB
stdin
Standard input is empty
stdout
--- static polymorphism
edge:	1
weighted_edge:	3.14
derived_edge:	42
bogus:	1

--- runtime polymorphism
edge:	1
weighted_edge:	3.14
bogus:	42