fork(1) download
  1. #include <iostream>
  2. #include <memory>
  3.  
  4. struct copyableMovable
  5. {
  6. copyableMovable() { std::cout << "\tcopyableMovable()\t"; }
  7. copyableMovable(const copyableMovable&) noexcept { std::cout << "\tcopyableMovable(const copyableMovable&)\n"; }
  8. copyableMovable(copyableMovable&&) noexcept { std::cout << "\tcopyableMovable(copyableMovable&&)\n"; }
  9. };
  10.  
  11. struct onlyMovable
  12. {
  13. onlyMovable() { std::cout << "\tonlyMovable()\t"; }
  14. onlyMovable(onlyMovable&&) { std::cout << "\tonlyMovable(onlyMovable&&)\n"; }
  15. onlyMovable(const onlyMovable&) = delete;
  16. };
  17.  
  18. struct byValue
  19. {
  20. byValue(copyableMovable) { std::cout << "byValue(copyableMovable)\n"; }
  21. byValue(onlyMovable) { std::cout << "byValue(onlyMovable)\n"; }
  22. };
  23. struct byReference
  24. {
  25. byReference(copyableMovable&) { std::cout << "byReference(copyableMovable&)\n"; }
  26. byReference(onlyMovable&) { std::cout << "byReference(onlyMovable&)\n"; }
  27. };
  28. struct byConstReference
  29. {
  30. byConstReference(const copyableMovable&) { std::cout << "byConstReference(const copyableMovable&)\n"; }
  31. byConstReference(const onlyMovable&) { std::cout << "byConstReference(const onlyMovable&)\n"; }
  32. };
  33. struct byRvalueReference
  34. {
  35. byRvalueReference(copyableMovable&&) { std::cout << "byRvalueReference(copyableMovable&&)\n"; }
  36. byRvalueReference(onlyMovable&&) { std::cout << "byRvalueReference(onlyMovable&&)\n"; }
  37. };
  38.  
  39.  
  40. template <typename T, typename Arg>
  41. std::unique_ptr<T> without_forward(Arg arg)
  42. { return std::unique_ptr<T>(new T(arg)); }
  43.  
  44. template <typename T, typename Arg>
  45. std::unique_ptr<T> with_forward(Arg arg)
  46. { return std::unique_ptr<T>(new T(std::forward<Arg>(arg))); }
  47.  
  48.  
  49. int main()
  50. {
  51. std::cout << "\tIDEA\nPassing lvalues and rvalues to function that return unique_ptr for them.\nWe have two kinds of objects:\n";
  52. copyableMovable cm{}; std::cout << " - can be copied and moved along i. e. not restricted at all.\n";
  53. onlyMovable om{}; std::cout << " - can be moved but cannot be copied, i. e. unique_ptr or streams etc.\n";
  54.  
  55. std::cout << "\n\n\n\tWITHOUT FORWARD\n";
  56.  
  57. std::cout << "BY VALUE\n";
  58. std::cout << "Lvalue - copyable:\n"; auto val_copy_l = without_forward<byValue>(cm);
  59. std::cout << "\nLvalue - moveable:\n"; //auto val_move_l = without_forward<byValue>(om);
  60. std::cout << "Impossible, needs copy constructor.\n";
  61. std::cout << "\nRvalue - copyable:\n"; auto val_copy_r = without_forward<byValue>(copyableMovable{});
  62. std::cout << "\nRvalue - moveable:\n"; //auto val_move_r = without_forward<byValue>(onlyMovable{});
  63. std::cout << "Impossible, needs copy constructor.\n\n";
  64.  
  65. std::cout << "BY REFERENCE\n";
  66. std::cout << "Lvalue - copyable:\n"; auto ref_copy_l = without_forward<byReference>(cm);
  67. std::cout << "\nLvalue - moveable:\n"; //auto ref_move_l = without_forward<byReference>(om);
  68. std::cout << "Impossible, needs copy constructor\n";
  69. std::cout << "\nRvalue - copyable:\n"; auto ref_copy_r = without_forward<byReference>(copyableMovable{});
  70. std::cout << "\nRvalue - moveable:\n"; auto ref_move_r = without_forward<byReference>(onlyMovable{});
  71.  
  72. std::cout << "BY CONST REFERENCE\n";
  73. std::cout << "\nLvalue - copyable:\n"; auto cref_copy_l = without_forward<byConstReference>(cm);
  74. std::cout << "\nLvalue - moveable:\n"; //auto cref_move_l = without_forward<byConstReference>(om);
  75. std::cout << "Impossible, needs copy constructor\n";
  76. std::cout << "\nRvalue - copyable:\n"; auto cref_copy_r = without_forward<byConstReference>(copyableMovable{});
  77. std::cout << "\nRvalue - moveable:\n"; auto cref_move_r = without_forward<byConstReference>(onlyMovable{});
  78.  
  79. std::cout << "BY RVALUE REFERENCE\n";
  80. std::cout << "\nLvalue - copyable:\n"; //auto rref_copy_l = without_forward<byRvalueReference>(copyableMovable{});
  81. std::cout << "Lvalue - moveable:\n"; //auto rref_move_l = without_forward<byRvalueReference>(onlyMovable{});
  82. std::cout << "Rvalue - copyable:\n"; //auto rref_copy_r = without_forward<byRvalueReference>(copyableMovable{});
  83. std::cout << "Rvalue - moveable:\n"; //auto rref_move_r = without_forward<byRvalueReference>(onlyMovable{});
  84. std::cout << "Evarything impossible: they all need an rvalue, but receive an lvalue.\n";
  85.  
  86. std::cout << "\nWithout forward - short summary:\nPassing by value is impossible for onlyMovable."
  87. "\nPassing by lvalue reference is impossible for onlyMovable rvalues."
  88. "\nPassing by rvalue does not work at all.\n";
  89.  
  90.  
  91. std::cout << "\n\n\n\tWITH FORWARD\n";
  92.  
  93. std::cout << "BY VALUE\n";
  94. std::cout << "Lvalue - copyable:\n"; auto val_copy_lf = with_forward<byValue>(cm);
  95. std::cout << "\nLvalue - moveable:\n"; //auto val_move_lf = with_forward<byValue>(om);
  96. std::cout << "Impossible, needs copy constructor.\n";
  97. std::cout << "\nRvalue - copyable:\n"; auto val_copy_rf = with_forward<byValue>(copyableMovable{});
  98. std::cout << "\nRvalue - moveable:\n"; auto val_move_rf = with_forward<byValue>(onlyMovable{});
  99.  
  100. std::cout << "\nBY REFERENCE\n";
  101. std::cout << "Lvalue - copyable:\n"; //auto ref_copy_lf = with_forward<byReference>(cm);
  102. std::cout << "Lvalue - moveable:\n"; //auto ref_move_lf = with_forward<byReference>(om);
  103. std::cout << "Rvalue - copyable:\n"; //auto ref_copy_rf = with_forward<byReference>(copyableMovable{});
  104. std::cout << "Rvalue - moveable:\n"; //auto ref_move_rf = with_forward<byReference>(onlyMovable{});
  105. std::cout << "All impossible - lvalue needed, not rvalue.\n";
  106.  
  107. std::cout << "\nBY CONST REFERENCE\n";
  108. std::cout << "\nLvalue - copyable:\n"; auto cref_copy_lf = with_forward<byConstReference>(cm);
  109. std::cout << "\nLvalue - moveable:\n"; //auto cref_move_lf = with_forward<byConstReference>(om);
  110. std::cout << "Impossible, needs copy constructor\n";
  111. std::cout << "\nRvalue - copyable:\n"; auto cref_copy_rf = with_forward<byConstReference>(copyableMovable{});
  112. std::cout << "\nRvalue - moveable:\n"; auto cref_move_rf = with_forward<byConstReference>(onlyMovable{});
  113.  
  114. std::cout << "\nBY RVALUE REFERENCE\n";
  115. std::cout << "\nLvalue - copyable:\n"; auto rref_copy_lf = with_forward<byRvalueReference>(copyableMovable{});
  116. std::cout << "Lvalue - moveable:\n"; auto rref_move_lf = with_forward<byRvalueReference>(onlyMovable{});
  117. std::cout << "Rvalue - copyable:\n"; auto rref_copy_rf = with_forward<byRvalueReference>(copyableMovable{});
  118. std::cout << "Rvalue - moveable:\n"; auto rref_move_rf = with_forward<byRvalueReference>(onlyMovable{});
  119. std::cout << "With forward - short summary:\nPassing by value is impossible for onlyMovable lvalue.\n"
  120. "Passing by non const lvalue reference does not work at all.\n"
  121. "Passing by const lvalue reference is impossible for onlyMovable lvalue.\n";
  122.  
  123. std::cout << "\n\nSUMMARY\nAfter enabling forward in function rerturning unique_ptr to it's argument:\n"
  124. " - passing onlyMovable rvalue by value becomes possible\n"
  125. " - passing lvalue copyableMovable and all rvalues by non const lvalue reference becomes impossible\n"
  126. " - passing by const lvalue reference does not change\n"
  127. " - passing by rvalue reference becomes possible for both lvalues and rvalues of both copyableMovable and onlyMovable\n"
  128. "Experiment overlooks onlyCopyable type.\n";
  129. }
Success #stdin #stdout 0s 4184KB
stdin
Standard input is empty
stdout
	IDEA
Passing lvalues and rvalues to function that return unique_ptr for them.
We have two kinds of objects:
	copyableMovable()	 - can be copied and moved along i. e. not restricted at all.
	onlyMovable()	 - can be moved but cannot be copied, i. e. unique_ptr or streams etc.



	WITHOUT FORWARD
BY VALUE
Lvalue - copyable:
	copyableMovable(const copyableMovable&)
	copyableMovable(const copyableMovable&)
byValue(copyableMovable)

Lvalue - moveable:
Impossible, needs copy constructor.

Rvalue - copyable:
	copyableMovable()		copyableMovable(const copyableMovable&)
byValue(copyableMovable)

Rvalue - moveable:
Impossible, needs copy constructor.

BY REFERENCE
Lvalue - copyable:
	copyableMovable(const copyableMovable&)
byReference(copyableMovable&)

Lvalue - moveable:
Impossible, needs copy constructor

Rvalue - copyable:
	copyableMovable()	byReference(copyableMovable&)

Rvalue - moveable:
	onlyMovable()	byReference(onlyMovable&)
BY CONST REFERENCE

Lvalue - copyable:
	copyableMovable(const copyableMovable&)
byConstReference(const copyableMovable&)

Lvalue - moveable:
Impossible, needs copy constructor

Rvalue - copyable:
	copyableMovable()	byConstReference(const copyableMovable&)

Rvalue - moveable:
	onlyMovable()	byConstReference(const onlyMovable&)
BY RVALUE REFERENCE

Lvalue - copyable:
Lvalue - moveable:
Rvalue - copyable:
Rvalue - moveable:
Evarything impossible: they all need an rvalue, but receive an lvalue.

Without forward - short summary:
Passing by value is impossible for onlyMovable.
Passing by lvalue reference is impossible for onlyMovable rvalues.
Passing by rvalue does not work at all.



	WITH FORWARD
BY VALUE
Lvalue - copyable:
	copyableMovable(const copyableMovable&)
	copyableMovable(copyableMovable&&)
byValue(copyableMovable)

Lvalue - moveable:
Impossible, needs copy constructor.

Rvalue - copyable:
	copyableMovable()		copyableMovable(copyableMovable&&)
byValue(copyableMovable)

Rvalue - moveable:
	onlyMovable()		onlyMovable(onlyMovable&&)
byValue(onlyMovable)

BY REFERENCE
Lvalue - copyable:
Lvalue - moveable:
Rvalue - copyable:
Rvalue - moveable:
All impossible - lvalue needed, not rvalue.

BY CONST REFERENCE

Lvalue - copyable:
	copyableMovable(const copyableMovable&)
byConstReference(const copyableMovable&)

Lvalue - moveable:
Impossible, needs copy constructor

Rvalue - copyable:
	copyableMovable()	byConstReference(const copyableMovable&)

Rvalue - moveable:
	onlyMovable()	byConstReference(const onlyMovable&)

BY RVALUE REFERENCE

Lvalue - copyable:
	copyableMovable()	byRvalueReference(copyableMovable&&)
Lvalue - moveable:
	onlyMovable()	byRvalueReference(onlyMovable&&)
Rvalue - copyable:
	copyableMovable()	byRvalueReference(copyableMovable&&)
Rvalue - moveable:
	onlyMovable()	byRvalueReference(onlyMovable&&)
With forward - short summary:
Passing by value is impossible for onlyMovable lvalue.
Passing by non const lvalue reference does not work at all.
Passing by const lvalue reference is impossible for onlyMovable lvalue.


SUMMARY
After enabling forward in function rerturning unique_ptr to it's argument:
 - passing onlyMovable rvalue by value becomes possible
 - passing lvalue copyableMovable and all rvalues by non const lvalue reference becomes impossible
 - passing by const lvalue reference does not change
 - passing by rvalue reference becomes possible for both lvalues and rvalues of both copyableMovable and onlyMovable
Experiment overlooks onlyCopyable type.