我知道这可用于执行完美转发:
template <typename A>
void foo(A&&) { /* */ }
这可以用于在某种类型上执行完美转发:
template <typename A, std::enable_if_t<std::is_same<std::decay_t<A>, int>::value, int> = 0>
void foo(A&&) { /* */ }
但这些只是函数的模板,这意味着,这些函数会扩展为某些函数,然后将其用于可能使用它的每个特殊情况。但是,这些扩展到:
void foo(A&)
和void foo(A&&)
或
void foo(A&)
和void foo(A)
我一直认为,这将是第一个,但后来我注意到,在那种情况下,你将无法使用A const
作为函数的参数,这当然有效。
然而,如果您使用正常的非常数左值,则第二个将是不明确的。它会调用foo(A&)
还是foo(A)
?
答案 0 :(得分:5)
这是第一个。第二个没有意义:没有A
,A&&
是非引用类型。
如果参数是 cv T
类型的左值,则A
推断为 cv T&
。如果参数是 cv T
类型的右值,则A
推断为 cv T
和A&&
是 cv T&&
。因此,当您传入const
左值时,生成的特化可以接受const
参数。
答案 1 :(得分:2)
他们最初被称为&#34; Univeral 参考&#34;作者:Scott Meyers,现在&#34; 转发参考&#34;。
如您所见,参考部分未发生变化。您传入任何类型的rvalue
,都会获得rvalue
个引用。您传入任何类型的lvalue
,并获得左值参考。生活就是这么简单。