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";
}