前回、std::moveを紹介したが、右辺値参照のためにはもう1つ
std::forwardが用意される
namespace std { template <class T> struct identity { typedef T type; }; template <class T> inline T&& forward(typename identity<T>::type&& x) { return x; } }
まず、右辺値参照(&&)では、参照値(&)も受け取ることができる
これがバグの温床になってしまうことがある
struct hoge { hoge(int&) {} }; template <class T, class A> shared_ptr<T> factory(A&& a) { return shared_ptr<T>(new T(a)); } int main() { shared_ptr<hoge> p1 = factory<hoge>(3); // OK...エラーになってほしかった int value = 3; shared_ptr<hoge> p2 = factory<hoge>(value); // OK return 0; }
std::forwardを使用することで、右辺値参照で受け取った値を安全に転送することができる
struct hoge { hoge(int&) {} }; template <class T, class A1> shared_ptr<T> factory(A1&& a1) { return shared_ptr<T>(new T(forward<A1>(a1))); } int main() { shared_ptr<hoge> p1 = factory<hoge>(3); // エラー! int value = 3; shared_ptr<hoge> p2 = factory<hoge>(value); // OK return 0; }
↓によると、「完璧な転送」だそうな
N2027 - A Brief Introduction to Rvalue References