2

我正在学习 C++ 模板。有人可以解释这段代码的每一点吗

template <class T>
struct identity
{
    typedef T type;
};
template <class T>
T&& forward(typename identity<T>::type&& a)
{
    return a;
}
4

2 回答 2

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);
}
于 2013-05-17T07:39:09.190 回答
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>::typetype编译器无法将返回的类型(无论它可能多么明显)推断为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;
}
于 2013-05-17T15:39:59.543 回答