C++ 为什么std::forward有两个签名?
如所述,C++ 为什么std::forward有两个签名?,c++,c++11,stl,rvalue-reference,rvalue,C++,C++11,Stl,Rvalue Reference,Rvalue,如所述,std::forward有两个签名: template <class T> T&& forward (typename remove_reference<T>::type& arg) noexcept; template <class T> T&& forward (typename remove_reference<T>::type&& arg) noexcept; 当我们调用fw
std::forward
有两个签名:
template <class T> T&& forward (typename remove_reference<T>::type& arg) noexcept;
template <class T> T&& forward (typename remove_reference<T>::type&& arg) noexcept;
当我们调用fwd(0)
时,T
推断为int
(T
具有类型int&
)。然后我们调用std::forward(t)
。该调用的结果是int&
类型的表达式,因此选择了重载
函数的第二个版本,程序将“右值”打印到标准输出
当我们调用fwd(i)
(其中i是一些int变量),T
推断为int&
(T
具有类型int&
)。然后我们调用std::forward(t)
。该调用的结果(应用引用折叠规则后)是int&
类型的表达式,因此选择了重载
函数的第一个版本,程序将“左值”打印到标准输出
在这两种情况下,我们都使用std::forward
的第一个重载(使用typename remove\u reference::type&arg的重载)。这是因为即使t
的类型是int&
它也会绑定到左值引用(因为“rvalue reference to something”类型的命名变量本身就是左值,而左值不能绑定到rvalue引用)
问题1:
std::forward
的第二个重载是为了什么?你能想出一些实际的例子,使用重载通过右值引用获取arg
问题2:
说:
两个签名返回的内容相同:
static_cast<decltype(arg)&&>(arg)
两个重载版本的std::forward
都应该返回static\u cast(arg)
。我说得对吗
你认为cplusplus.com的引用是错误的吗?class Foo{};
class Foo {};
auto f = [](){ return Foo{}; };
auto g = []()->Foo&{ static Foo x; return x; };
template<class T>
std::false_type is_rvalue( T& ) { return {}; }
template<class T>
std::true_type is_rvalue( T&& ) { return {}; }
template<class T, class F>
auto test( F&& f ) {
return is_rvalue( std::forward<T>( f() ) );
}
int main() {
std::cout << test<Foo>(f) << "," << test<Foo&>(g) << "\n";
}
自动f=[](){return Foo{};};
autog=[]()->Foo&{static Foo x;return x;};
模板
std::false_类型是_-rvalue(T&){return{};}
模板
std::true_类型是_-rvalue(T&&){return{};}
模板
自动测试(F&F){
返回值为右值(std::forward(f());
}
int main(){
std::看不见第一个问题的答案。@TartanLlama,一个人有一堆const
和const\u cast
贯穿整个过程。cplusplus.com
不是cppreference
cppreference.com
是cppreference
。知道区别。@Nawaz说明区别可能是,也可能不是n topic(我自己觉得cppreference更可靠)@Yakk,如果你发现一个bug,你可以自己修复:)
cannot bind ‘std::remove_reference<int>::type {aka int}’ lvalue to ‘int&&’
class Foo {};
auto f = [](){ return Foo{}; };
auto g = []()->Foo&{ static Foo x; return x; };
template<class T>
std::false_type is_rvalue( T& ) { return {}; }
template<class T>
std::true_type is_rvalue( T&& ) { return {}; }
template<class T, class F>
auto test( F&& f ) {
return is_rvalue( std::forward<T>( f() ) );
}
int main() {
std::cout << test<Foo>(f) << "," << test<Foo&>(g) << "\n";
}