C++ テンプレートを勉強しています。誰かがこのコードのすべてのビットを説明できますか
template <class T>
struct identity
{
typedef T type;
};
template <class T>
T&& forward(typename identity<T>::type&& a)
{
return a;
}
C++ テンプレートを勉強しています。誰かがこのコードのすべてのビットを説明できますか
template <class T>
struct identity
{
typedef T type;
};
template <class T>
T&& forward(typename identity<T>::type&& a)
{
return a;
}
my_forward
まず、この呼び出しを許可するには、別の特殊化が必要です。
int a;
my_forward<int>(a);
したがって、my_forward
次のような参照に特化します。
template <class T>
T&& my_forward(typename identity<T>::type& a)
{
return static_cast<T&&>(a);
}
しかし、この場合、
int a;
my_forward<int&>(std::ref(a));
あいまいです:
note: candidate function [with T = int &]
T&& my_forward(typename identity<T>::type&& a)
^
note: candidate function [with T = int &]
T&& my_forward(typename identity<T>::type& a)
^
それを避けるには、次std::remove_reference
の代わりに使用する必要がありidentity
ます。
template <class T>
T&& my_forward(typename std::remove_reference<T>::type&& a)
{
return static_cast<T&&>(a);
}
template <class T>
T&& my_forward(typename std::remove_reference<T>::type& a)
{
return static_cast<T&&>(a);
}
template <class T>
struct identity
{
typedef T type;
};
この部分は、テンプレート引数として渡す型の名前付きidentity
パブリック メンバーを保持する名前付きクラス テンプレートを定義しています。あなたの例では、部分的または明示的な特殊化がないため、渡される型はすべてです。typedef
type
identity
type
template <class T>
T&& forward(typename identity<T>::type&& a)
{
return a;
}
forward
によって返される型への右辺値参照を取る関数テンプレートidentity<T>::type
です。によって返される型(明らかであっても) は、コンパイラによって(型が依存型type
であるため) であると推測できないため、 のテンプレート引数を明示的に指定する必要があります。T
forward
右辺値参照構文(戻り値の型の場合) は、型がテンプレート引数であるため、(非公式に)ユニバーサル参照&&
と呼ばれるものも示します。これは、戻り値の型が、関数によって返される右辺値と左辺値の両方にバインドできることを意味します。T
返される型はテンプレート パラメーターではないため、パラメーターの型identity<T>::type&&
はユニバーサル参照ではありません。これは、パラメーターが右辺値のみを受け入れることができることを意味します。それには、パラメーターに左辺値を指定する必要があります。move
forward
int main()
{
int n{0};
forward<int>(std::move(n));
}
そして最後に、パラメーターa
を右辺値参照に戻します。ただし、移動する必要があるため、パラメーターを に戻すことはできT&&
ません。a
template <class T>
T&& forward(typename identity<T>::type&& a)
{
return std::move(a);
}
それ以外の場合は、代わりに左辺値参照を返します。
template <class T>
T& forward(typename identity<T>::type&& a)
{
return a;
}