6. Universal referenceの働き
• lvalueで初期化するとlvalue referenceに,rvalueで初期
化するとrvalue referenceになる
// param is a universal reference
template<typename T>
void f(T&& param);
Widget w;
// param's type is Widget&, an lvalue
reference
f(w);
// param's type is Widget&&, an rvalue
reference
f(std::move(w));
7. Universal referenceが
現れる2つの文脈
• テンプレートパラメータ
// param is a universal reference
template<typename T>
void f(T&& param);
• auto宣言
// x is a universal reference
int a = 0;
auto&& x = a;
• 共通点:型推論の存在
8. Universal referenceでない例
• T&& の形をしていても型推論が起こらなければ
universal referenceではない
// no type deduction;
// param is an rvalue reference
void f(Widget&& param);
// no type deduction;
// param is an rvalue reference
Widget&& var1 = Widget();
10. 紛らわしい例 (1)
• 正確に T&& の形になっている必要がある
// param is an rvalue reference
template<typename T>
void f(std::vector<T>&& param);
// param is an rvalue reference
template<typename T>
void f(const T&& param);
11. 紛らわしい例 (2)
• テンプレートを使っていて正確に T&& の形になってい
てもuniversal referenceではない場合がある
template<class T, class Allocator =
allocator<T>>
class vector {
public:
// x is an rvalue reference
void push_back(T&& x);
};
• Tはvectorの実体化の際に決まり,push_backで型推
論は起こらない
12. 紛らわしい例 (3)
• Variadic templateのtemplate parameter packも
universal referenceになりうる
template<class T, class Allocator =
allocator<T>>
class vector {
public:
// args are zero or more universal
references
template <class... Args>
void emplace_back(Args&&... args);
};
13. 紛らわしい例 (4)
• Generic lambdaの引数ではauto&&の形をとる
// func is a universal reference
// params are zero or more universal
references
auto timeFuncInvocation =
[](auto&& func, auto&&... params)
{...};