fork download
  1. #include <iostream>
  2. struct Dim;
  3. struct Group;
  4.  
  5. struct Cross {
  6. int i;
  7. Cross(int l):i(l) { std::cout << "Cross() = " << (uint64_t)this << std::endl;}
  8. Dim dim();
  9. };
  10.  
  11. struct Dim {
  12. Cross * ptr;
  13. explicit Dim(Cross * c):ptr(c) {
  14. std::cout << "Dim(Cross*) = " << (uint64_t)this << " : " << (uint64_t)ptr << std::endl;
  15. }
  16. Dim(Dim && d):ptr(d.ptr) {
  17. d.ptr = nullptr;
  18. std::cout << "Dim(&&) = " << (uint64_t)this << " : " << (uint64_t)ptr << std::endl;
  19. }
  20. Group group();
  21. };
  22.  
  23. struct Group {
  24. Dim * ptr;
  25. explicit Group(Dim * c):ptr(c) {
  26. std::cout << "Group(Dim*) = " << (uint64_t)this << " : " << (uint64_t)ptr << std::endl;
  27. }
  28. Group(Group && d):ptr(d.ptr) {
  29. d.ptr = nullptr;
  30. std::cout << "Group(&&) = " << (uint64_t)this << " : " << (uint64_t)ptr << std::endl;
  31. }
  32.  
  33. };
  34.  
  35. Dim Cross::dim() {
  36. Dim d(this);
  37. return d;
  38. }
  39.  
  40. Group Dim::group() {
  41. Group g(this);
  42. return g;
  43. }
  44.  
  45. template<typename D>
  46. struct Op {
  47. D g;
  48. Op(Op && o):g(std::move(o.g)) {
  49. std::cout << "Op(&&) = " << (uint64_t)this << " : " << (uint64_t)g.ptr << std::endl;
  50. }
  51. Op(D && gg):g(std::move(gg)) {
  52. std::cout << "Op(D&&) = " << (uint64_t)this << " : " << (uint64_t)g.ptr << std::endl;
  53. }
  54. };
  55.  
  56. template<typename D>
  57. struct Cons {
  58. D op;
  59. Cons(Cons && c):op(std::move(c.op)) {
  60. std::cout << "Cons(&&) = " << (uint64_t)this << " : " << (uint64_t)op.g.ptr << std::endl;
  61. }
  62. explicit Cons(D && gg):op(std::move(gg)) {
  63. std::cout << "Cons(Op&&) = " << (uint64_t)this << " : " << (uint64_t)op.g.ptr << std::endl;
  64. }
  65. };
  66.  
  67. template<typename D>
  68. decltype(auto) make_consumer1(D &&d) {
  69. auto op = Op<std::decay_t<D>>(std::move(d));
  70. return Cons<std::decay_t<decltype(op)>>(std::move(op));
  71. }
  72. template<typename G>
  73. decltype(auto) make_consumer2(G && g) { // <---------если здесь передавать аргумент по значению, то проблема исчезает.
  74. auto gop = Op<std::decay_t<G>>(std::move(g));
  75. return Cons<std::decay_t<decltype(gop)>>(std::move(gop));
  76. }
  77.  
  78.  
  79. int main() {
  80. Cross c(10);
  81. auto cons1 = make_consumer1(c.dim());
  82. std::cout << "cons1 "<< cons1.op.g.ptr->i << std::endl;
  83. auto cons2 = make_consumer2(cons1.op.g.group());
  84. std::cout << cons2.op.g.ptr->ptr->i << std::endl;
  85. return 0;
  86. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Cross() = 140734262482112
Dim(Cross*) = 140734262482144 : 140734262482112
Dim(&&) = 140734262482176 : 140734262482112
Op(D&&) = 140734262482176 : 140734262482112
Dim(&&) = 140734262482128 : 140734262482112
Op(&&) = 140734262482128 : 140734262482112
Cons(Op&&) = 140734262482128 : 140734262482112
cons1 10
Group(Dim*) = 140734262482160 : 140734262482128
Group(&&) = 140734262482192 : 140734262482128
Op(D&&) = 140734262482192 : 140734262482128
Group(&&) = 140734262482176 : 140734262482128
Op(&&) = 140734262482176 : 140734262482128
Cons(Op&&) = 140734262482176 : 140734262482128
10