据我了解,std::forward<T>(x)
相当于static_cast<T&&>(x)
。
但是从我看到的情况来看,static_cast<T>(x)
似乎做了同样的事情,如下面的code
因此,我的问题是std::forward<T>
如果static_cast<T&&>(x)
被实现为static_cast<T>(x)
而不是sampleApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/Home");
$stateProvider
.state('Product', {
templateUrl: "templates/Products.html",
url: '/Product',
controller: 'MainCtrl2 as pc'
})
.state('Login', {
templateUrl: "templates/Login.html",
url: "/Login",
controller: 'loginCtrl'
})
.state('SignUp', {
templateUrl: "templates/SignUp.html",
url: "/SignUp",
controller: 'SignUpController'
})
.state('Home', {
templateUrl: "templates/Home.html",
url: "/Home"
})
.state('Feedback', {
templateUrl: "templates/Feedback.html",
url: "/Feedback"
})
;
});
,如果两者具有相同的效果?
答案 0 :(得分:11)
因为完美转发允许传递 r值引用和 l值引用。这是通过reference collapsing完成的:
T = int --> T&& = int&&
T = int& --> T&& = int& && = int&
T = int&& --> T&& = int&& && = int&&
在使用static_cast<T>
的示例中,您只是丢失了r值引用。它适用于原始类型(因为传递int
通常是复制CPU寄存器值),但对复杂类型来说很糟糕,因为它会导致通过复制ctors创建临时对象。
答案 1 :(得分:2)
如果T&&
是左值参考,则T
是一个值,然后static_cast<T>
使副本不是右值参考。
该副本将绑定到右值引用(就像引用一样),但是复制/移动ctors可能会被不必要地调用,并且它不是elision的候选者。
static_cast<T&&>
同时只会转换为右值参考。
他们是完全相同的。
答案 2 :(得分:0)
我同意Yakk,但它比那更糟。
editGridRow
这将始终创建副本。向量未移动,因为void foo(const std::vector<int> &vec);
template<typename T>
void callFoo(T &&data)
{
foo(static_cast<T>(data));
}
int main()
{
callFoo(std::vector<int>{/*...*/});
}
作为表达式,是data
类型的左值,即使替换类型为std::vector<int>
。请注意,std::vector<int>&&
为T
,而非std::vector<int>
。故事的道德:使用标准库,它做对了,名称std::vector<int> &&
也比forward
更好地捕获意图。