回复
有什么区别?
实际上没有区别,执行的预期结果是一样的,只是写法更冗长
您只是定义 T 并使用通过 typename 定义的类型,实际上没有区别。
为什么后者是通常的实现方式?
我没有关注这个更新,所以我不能说他们是否在他们的存储库中正式使用了这个代码,它可能是别人的实现而不是官方的,不管是什么原因:
他们选择这样做,即使 两种实现都无效对于真实场景。
请注意,两者具有相同的结果,并且在执行过程中根本不会发散,也就是说,在实际场景中,它们之间的发散不会导致任何差异或运行/编译错误或类似情况
代码审查
错过了为编译成功添加“typename”
template<typename T>
struct identity {
typedef T type;
};
template<typename T>
T&& forward(typename identity<T>::type&& param)
{
return static_cast<**typename** identity<T>::type&&>(param);
}
说明
为什么无效
考虑到下面的代码,参数 T 是“int”,包含返回类型是“int&&”,同时期望一个右值类型的函数参数 (int&&),但传递了一个左值 int&,从而产生编译错误
#include <iostream>
template<typename T>
T&& forward(T&& param)
{
return static_cast<T&&>(param);
}
int main() {
int value = 5;
forward<int>(value);
return 1;
}
真实风景
第 25 行,redir(5),导致编译错误,这将是一个真实的场景。
错误是因为引用 void redir 的 template T 是 int 类型并且在调用 forward 时(param) 它正在传递 param 这是一个左值变量,在为什么无效
部分中进行了解释
#include <iostream>
template<typename T>
T&& forward(T&& param)
{
return static_cast<T&&>(param);
}
void print(int &&value){
std::cout << "rvalue: " << value << std::endl;
}
void print(int &value){
std::cout << "lvalue: " << value << std::endl;
}
template <class T>
void redir(T &¶m){
print(forward<T>(param));
}
int main() {
int value = 5;
redir(value);
**redir(5);**
return 0;
}
解决方案
目前代码已经更新,问题已经修复,您可以查看:https://en.cppreference.com/w/cpp/utility/forward。
代码将类似于:
#include <iostream>
template< class T >
T&& forward( std::remove_reference_t<T> &¶m)
{
return static_cast<T&&>(param);
}
template< class T >
T&& forward( std::remove_reference_t<T> ¶m)
{
return static_cast<T&&>(param);
}
void print(int &&value){
std::cout << "rvalue: " << value << std::endl;
}
void print(int &value){
std::cout << "lvalue: " << value << std::endl;
}
template <class T>
void redir(T &¶m){
print(forward<T>(param));
}
int main() {
int value = 5;
redir(value);
redir(5);
return 0;
}
std::remove_reference_t 是可选的,即使不使用它,结果也是一样的。
由于良好的做法,他们决定使用 remove_reference_t,也就是说,他们正在强化第一个函数需要 int& 而第二个函数需要 int&&。
为什么 std::remove_reference 无关紧要
虽然它不会改变代码执行中的预期结果,但由于良好的编程实践,它很重要,可以说它强化了预期结果。
嗯,但结果解释没有改变是由于以下转换规则:
TR R
T& & -> T& // lvalue reference to cv TR -> lvalue reference to T
T& && -> T& // rvalue reference to cv TR -> TR (lvalue reference to T)
T&& & -> T& // lvalue reference to cv TR -> lvalue reference to T
T&& && -> T&& // rvalue reference to cv TR -> TR (rvalue reference to T)
我们可以,获得右值 (T&&) 的唯一方法是通过转换 T&& + T&&,或仅 T&&。
为什么必须在一个函数中使用 2 个函数 (std::forward) 而不仅仅是 static_cast
<int&&> int&& && forward(int&& &¶m) will result int&& forward(int&& param)
<int&> int& && forward(int& &¶m) will result int& forward(int& param)
<int> int && forward(int &¶m) will result int&& forward(int&& param)
请注意,第二个函数:T&& forward(std::remove_reference_t ¶m) 仅填充缺少的内容
<int> int && forward(int ¶m) will result int&& forward(int& param)
因此,您需要声明 2 个 std::forward 函数。