fork download
  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4.  
  5. #include <boost/variant.hpp>
  6.  
  7. class Value {
  8. int x;
  9. public:
  10. explicit Value(int x) : x(x) {}
  11. Value(Value&&) = default;
  12. Value(const Value&) = delete;
  13. ~Value() { x = 100500; }
  14.  
  15. int peek() const { return x; }
  16. };
  17.  
  18. Value fa() {
  19. Value a(1);
  20. return a;
  21. }
  22. Value ga() {
  23. Value a(1);
  24. Value& ra = a;
  25. return move(ra);
  26. }
  27. auto ha() {
  28. Value a(1);
  29. return [aa(move(a))]() mutable -> Value { return move(aa); };
  30. }
  31.  
  32. using Either = boost::variant<Value, string>;
  33.  
  34. Either&& emove(Either& e) { return static_cast<Either&&>(e); }
  35.  
  36. Either fe() {
  37. Either a("aaa");
  38. return a;
  39. }
  40. Either ge() {
  41. Either a(Value(123));
  42. Either& ra = a;
  43. // cannot explicitly move, had to trick with static-cast
  44. // return move(ra);
  45. return emove(ra);
  46. }
  47. auto he() {
  48. Either a(Value(456));
  49. cout << "he : " << &a << endl;
  50. // cannot bind to moved
  51. // return [=]() mutable -> Either { return a; };
  52. // return [a(move(a))]() mutable -> Either { return move(a); }
  53. return [&a, aa(emove(a))]() mutable -> Either {
  54. cout << "ll : " << &aa << " != " << &a << endl;
  55. return emove(aa);
  56. };
  57. }
  58.  
  59. Value peek(Either&& e) {
  60. return boost::get<Value>(emove(e));
  61. }
  62. Value peekpeek(Either e) {
  63. return peek(emove(e));
  64. }
  65.  
  66.  
  67. int main() {
  68. cout << boost::get<Value>(ge()).peek() << endl;
  69. cout << boost::get<Value>(he()()).peek() << endl;
  70. }
Success #stdin #stdout 0s 4504KB
stdin
Standard input is empty
stdout
123
he : 0x7ffdf9defad0
ll : 0x7ffdf9defb78 != 0x7ffdf9defad0
456