我正在学习C ++模板。有人可以解释这段代码的每一点
template <class T>
struct identity
{
typedef T type;
};
template <class T>
T&& forward(typename identity<T>::type&& a)
{
return a;
}
答案 0 :(得分:2)
首先,您需要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);
}
答案 1 :(得分:2)
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
返回的类型的rvalue-reference。 type
返回的类型(无论多么明显)都不能被编译器推导为T
(因为类型是dependent type),所以你必须明确指定模板参数forward
。
rvalue-reference语法&&
(对于return-type)也表示什么是(非正式地)称为通用引用,因为类型T
是一个模板参数。这意味着return-type可以绑定到函数返回的rvalues和lvalues。
参数类型identity<T>::type&&
不是通用引用,因为返回的类型不是模板参数。这意味着参数只能接受rvalues。这将要求我们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;
}