fork(2) download
  1. #include <iostream>
  2. #include <type_traits>
  3. #include <memory>
  4. using namespace std;
  5.  
  6. template<typename T> struct foo {
  7. virtual foo& operator<<(const T& e) const { std::cout << "check foo\n"; }
  8. };
  9.  
  10. struct derived : foo<int> {
  11. virtual derived& operator<<(const int& e) const { std::cout << "check derived\n"; }
  12. };
  13.  
  14. template<typename T> struct genericDerived : foo<T> {
  15. virtual derived& operator<<(const T& e) const { std::cout << "check genericDerived\n"; }
  16. };
  17.  
  18. //////
  19.  
  20. namespace detail
  21. {
  22. template<typename Foo, typename T>
  23. const std::shared_ptr<Foo>& dispatch_lshift(const std::shared_ptr<Foo>& o, const T& e, const std::true_type& enabler)
  24. {
  25. *o << e;
  26. return o;
  27. }
  28. }
  29.  
  30. template<typename Foo, typename T>
  31. const std::shared_ptr<Foo>& operator<<(const std::shared_ptr<Foo>& o, const T& e)
  32. {
  33. return detail::dispatch_lshift(o, e, std::is_convertible<Foo*, foo<T>* >());
  34. }
  35.  
  36. int main()
  37. {
  38. auto f = make_shared<foo<int>>();
  39. f << 1;
  40.  
  41. auto d = make_shared<derived>();
  42. d << 2;
  43.  
  44. auto g = make_shared<genericDerived<int>>();
  45. g << 3;
  46.  
  47. auto x = make_shared<int>();
  48. // x << 4; // correctly FAILS to compile
  49. }
  50.  
Success #stdin #stdout 0s 2968KB
stdin
Standard input is empty
stdout
check foo
check derived
check genericDerived