From Jason Turner

[forward]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5si95roo/{from.md → to.md} +43 -2
tmp/tmp5si95roo/{from.md → to.md} RENAMED
@@ -40,17 +40,58 @@ forwarded to `A`’s constructor as an rvalue. In the second call to
40
  constructor as an lvalue. In both cases, `A2` is deduced as `double`, so
41
  1.414 is forwarded to `A`’s constructor as an rvalue.
42
 
43
  — *end example*]
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  ``` cpp
46
  template<class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
47
  ```
48
 
49
  *Returns:* `static_cast<remove_reference_t<T>&&>(t)`.
50
 
51
- [*Example 2*:
52
 
53
  ``` cpp
54
  template<class T, class A1>
55
  shared_ptr<T> factory(A1&& a1) {
56
  return shared_ptr<T>(new T(std::forward<A1>(a1)));
@@ -63,11 +104,11 @@ struct A {
63
  };
64
 
65
  void g() {
66
  A a;
67
  shared_ptr<A> sp1 = factory<A>(a); // ``a'' binds to A(const A&)
68
- shared_ptr<A> sp1 = factory<A>(std::move(a)); // ``a'' binds to A(A&&)
69
  }
70
  ```
71
 
72
  In the first call to `factory`, `A1` is deduced as `A&`, so `a` is
73
  forwarded as a non-const lvalue. This binds to the constructor
 
40
  constructor as an lvalue. In both cases, `A2` is deduced as `double`, so
41
  1.414 is forwarded to `A`’s constructor as an rvalue.
42
 
43
  — *end example*]
44
 
45
+ ``` cpp
46
+ template<class T, class U>
47
+ [[nodiscard]] constexpr auto forward_like(U&& x) noexcept -> see below;
48
+ ```
49
+
50
+ *Mandates:* `T` is a referenceable type [[defns.referenceable]].
51
+
52
+ - Let *`COPY_CONST`*`(A, B)` be `const B` if `A` is a const type,
53
+ otherwise `B`.
54
+ - Let *`OVERRIDE_REF`*`(A, B)` be `remove_reference_t<B>&&` if `A` is an
55
+ rvalue reference type, otherwise `B&`.
56
+ - Let `V` be
57
+ ``` cpp
58
+ OVERRIDE_REF(T&&, COPY_CONST(remove_reference_t<T>, remove_reference_t<U>))
59
+ ```
60
+
61
+ *Returns:* `static_cast<V>(x)`.
62
+
63
+ *Remarks:* The return type is `V`.
64
+
65
+ [*Example 2*:
66
+
67
+ ``` cpp
68
+ struct accessor {
69
+ vector<string>* container;
70
+ decltype(auto) operator[](this auto&& self, size_t i) {
71
+ return std::forward_like<decltype(self)>((*container)[i]);
72
+ }
73
+ };
74
+ void g() {
75
+ vector v{"a"s, "b"s};
76
+ accessor a{&v};
77
+ string& x = a[0]; // OK, binds to lvalue reference
78
+ string&& y = std::move(a)[0]; // OK, is rvalue reference
79
+ string const&& z = std::move(as_const(a))[1]; // OK, is const&&
80
+ string& w = as_const(a)[1]; // error: will not bind to non-const
81
+ }
82
+ ```
83
+
84
+ — *end example*]
85
+
86
  ``` cpp
87
  template<class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
88
  ```
89
 
90
  *Returns:* `static_cast<remove_reference_t<T>&&>(t)`.
91
 
92
+ [*Example 3*:
93
 
94
  ``` cpp
95
  template<class T, class A1>
96
  shared_ptr<T> factory(A1&& a1) {
97
  return shared_ptr<T>(new T(std::forward<A1>(a1)));
 
104
  };
105
 
106
  void g() {
107
  A a;
108
  shared_ptr<A> sp1 = factory<A>(a); // ``a'' binds to A(const A&)
109
+ shared_ptr<A> sp2 = factory<A>(std::move(a)); // ``a'' binds to A(A&&)
110
  }
111
  ```
112
 
113
  In the first call to `factory`, `A1` is deduced as `A&`, so `a` is
114
  forwarded as a non-const lvalue. This binds to the constructor