fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <boost/ref.hpp>
  4. #include <boost/variant.hpp>
  5.  
  6. template <typename T>
  7. class CopyOrRef
  8. {
  9. private:
  10. typedef const T CopyType;
  11. typedef typename boost::reference_wrapper<const T> RefType;
  12. boost::variant<CopyType, RefType> _copyOrRef;
  13. public:
  14. CopyOrRef(const T & value) : _copyOrRef(value) { std::cout << "ctor 1" << std::endl; } // stores copy
  15. CopyOrRef(const T * ptr) : _copyOrRef(boost::ref(*ptr)) { std::cout << "ctor 2" << std::endl; } // stores reference
  16. CopyOrRef(const boost::reference_wrapper<T> & r) : _copyOrRef(boost::cref(r.get())) { std::cout << "ctor 3" << std::endl; } // stores reference
  17. CopyOrRef(const boost::reference_wrapper<const T> & r) : _copyOrRef(r) { std::cout << "ctor 4" << std::endl; } // stores reference
  18.  
  19. const T & get()
  20. {
  21. return _copyOrRef.which() == 0 ?
  22. *(boost::get<CopyType>(&_copyOrRef)) :
  23. *(boost::get<RefType>(&_copyOrRef));
  24. }
  25.  
  26. bool isCopy() const { return _copyOrRef.which() == 0; }
  27. bool isRef() const { return _copyOrRef.which() == 1; }
  28. };
  29.  
  30. class NonCopyConstructible
  31. {
  32. public:
  33. NonCopyConstructible() {}
  34. private:
  35. NonCopyConstructible(NonCopyConstructible & that);
  36. };
  37.  
  38. int main()
  39. {
  40.  
  41. std::string s = "s";
  42. CopyOrRef<std::string> test1(s);
  43. CopyOrRef<std::string> test2("ss");
  44. CopyOrRef<std::string> test3(&s);
  45. CopyOrRef<std::string> test4(boost::ref(s));
  46. CopyOrRef<std::string> test5(boost::cref(s));
  47.  
  48. std::cout << "test1: isCopy=" << test1.isCopy() << ", isRef=" << test1.isRef() << " : " << test1.get() << std::endl;
  49. std::cout << "test2: isCopy=" << test2.isCopy() << ", isRef=" << test2.isRef() << " : " << test2.get() << std::endl;
  50. std::cout << "test3: isCopy=" << test3.isCopy() << ", isRef=" << test3.isRef() << " : " << test3.get() << std::endl;
  51. std::cout << "test4: isCopy=" << test4.isCopy() << ", isRef=" << test4.isRef() << " : " << test4.get() << std::endl;
  52. std::cout << "test5: isCopy=" << test5.isCopy() << ", isRef=" << test5.isRef() << " : " << test5.get() << std::endl;
  53.  
  54. NonCopyConstructible t;
  55. CopyOrRef<NonCopyConstructible> tt(boost::cref(t));
  56.  
  57. }
  58.  
Success #stdin #stdout 0.01s 5288KB
stdin
Standard input is empty
stdout
ctor 1
ctor 1
ctor 2
ctor 3
ctor 4
test1: isCopy=1, isRef=0 : s
test2: isCopy=1, isRef=0 : ss
test3: isCopy=0, isRef=1 : s
test4: isCopy=0, isRef=1 : s
test5: isCopy=0, isRef=1 : s
ctor 4