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