我正在学习 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;
}