fork download
  1. #include <iostream>
  2.  
  3. class our_string {
  4. public:
  5. void reserve(std::size_t size) {}
  6. std::size_t size() const { return 0; }
  7. void append(const our_string& other) { }
  8. };
  9.  
  10. std::ostream& operator<<(std::ostream& lhs, const our_string& rhs) {
  11. return lhs;
  12. }
  13.  
  14. template<typename Derived> class ConcatenationExpressionBase {
  15. public:
  16. std::size_t size() const {
  17. return static_cast<Derived>(this)->size();
  18. }
  19. void add_to_string(our_string& result) const {
  20. return static_cast<Derived>(this)->add_to_string(result);
  21. }
  22. };
  23. class ConcatenateString : public ConcatenationExpressionBase<ConcatenateString> {
  24. public:
  25. ConcatenateString(const our_string* str)
  26. : p(str) {}
  27. ConcatenateString(const ConcatenateString& other)
  28. : p(other.p) {}
  29. const our_string* p;
  30. std::size_t size() const {
  31. return p->size();
  32. }
  33. void add_to_string(our_string& result) const {
  34. result.append(*p);
  35. }
  36. };
  37. template<typename LHS, typename RHS> class ConcatResult : public ConcatenationExpressionBase<ConcatResult<LHS, RHS>> {
  38. public:
  39. ConcatResult(LHS l, RHS r)
  40. : lhs(l), rhs(r) {}
  41. ConcatResult(const ConcatResult& other)
  42. : lhs(other.lhs), rhs(other.rhs) {}
  43. LHS lhs;
  44. RHS rhs;
  45. std::size_t size() const {
  46. return lhs.size() + rhs.size();
  47. }
  48. void add_to_string(our_string& result) const {
  49. lhs.add_to_string(result);
  50. rhs.add_to_string(result);
  51. }
  52. };
  53. ConcatResult<ConcatenateString, ConcatenateString> operator+(const our_string& lhs, const our_string& rhs) {
  54. return ConcatResult<ConcatenateString, ConcatenateString>(&lhs, &rhs);
  55. }
  56. template<typename LHS> ConcatResult<LHS, ConcatenateString> operator+(const ConcatenationExpressionBase<LHS>& lhs, const our_string& rhs) {
  57. return ConcatResult<LHS, ConcatenateString>(static_cast<const LHS&>(lhs), &rhs);
  58. }
  59. template<typename RHS> ConcatResult<ConcatenateString, RHS> operator+(const our_string& lhs, const ConcatenationExpressionBase<RHS>& rhs) {
  60. return ConcatResult<ConcatenateString, RHS>(&lhs, static_cast<const RHS&>(rhs));
  61. }
  62. template<typename LHS, typename RHS> ConcatResult<LHS, RHS> operator+(const ConcatenationExpressionBase<LHS>& lhs, const ConcatenationExpressionBase<RHS>& rhs) {
  63. return ConcatResult<LHS, RHS>(static_cast<const LHS&>(lhs), static_cast<const RHS&>(rhs));
  64. }
  65. template<typename T> std::ostream& operator<<(std::ostream& lhs, const ConcatenationExpressionBase<T>& rhs) {
  66. our_string result;
  67. result.reserve(rhs.size());
  68. rhs.add_to_string(result);
  69. return lhs << result;
  70. }
  71. int main() {
  72. std::cout << our_string() + our_string() + our_string();
  73. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In member function 'size_t ConcatenationExpressionBase<Derived>::size() const [with Derived = ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString>, size_t = unsigned int]':
prog.cpp:67:5:   instantiated from 'std::ostream& operator<<(std::ostream&, const ConcatenationExpressionBase<LHS>&) [with T = ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString>, std::ostream = std::basic_ostream<char>]'
prog.cpp:72:58:   instantiated from here
prog.cpp:17:49: error: no matching function for call to 'ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString>::ConcatResult(const ConcatenationExpressionBase<ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString> >* const)'
prog.cpp:41:5: note: candidates are: ConcatResult<LHS, RHS>::ConcatResult(const ConcatResult<LHS, RHS>&) [with LHS = ConcatResult<ConcatenateString, ConcatenateString>, RHS = ConcatenateString, ConcatResult<LHS, RHS> = ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString>]
prog.cpp:39:5: note:                 ConcatResult<LHS, RHS>::ConcatResult(LHS, RHS) [with LHS = ConcatResult<ConcatenateString, ConcatenateString>, RHS = ConcatenateString]
prog.cpp: In member function 'void ConcatenationExpressionBase<Derived>::add_to_string(our_string&) const [with Derived = ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString>]':
prog.cpp:68:5:   instantiated from 'std::ostream& operator<<(std::ostream&, const ConcatenationExpressionBase<LHS>&) [with T = ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString>, std::ostream = std::basic_ostream<char>]'
prog.cpp:72:58:   instantiated from here
prog.cpp:20:64: error: no matching function for call to 'ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString>::ConcatResult(const ConcatenationExpressionBase<ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString> >* const)'
prog.cpp:41:5: note: candidates are: ConcatResult<LHS, RHS>::ConcatResult(const ConcatResult<LHS, RHS>&) [with LHS = ConcatResult<ConcatenateString, ConcatenateString>, RHS = ConcatenateString, ConcatResult<LHS, RHS> = ConcatResult<ConcatResult<ConcatenateString, ConcatenateString>, ConcatenateString>]
prog.cpp:39:5: note:                 ConcatResult<LHS, RHS>::ConcatResult(LHS, RHS) [with LHS = ConcatResult<ConcatenateString, ConcatenateString>, RHS = ConcatenateString]
prog.cpp:20:64: error: return-statement with a value, in function returning 'void'
stdout
Standard output is empty