类型不推论为r值引用:为什么不呢?
请考虑以下代码:
class CMyClass {};
template<class T>
void func(T&& param) {
if (std::is_same<CMyClass, std::decay<T>::type>::value)
std::cout << "param is a CMyClass\n";
if (std::is_same<T, CMyClass&>::value)
std::cout << "param is a CMyClass reference\n";
else if (std::is_same<T, CMyClass&&>::value)
std::cout << "param is a CMyClass r-value reference\n";
else if (std::is_same<T, const CMyClass&>::value)
std::cout << "param is a const CMyClass reference\n";
else if (std::is_same<T, const CMyClass&&>::value)
std::cout << "param is a const CMyClass r-value reference\n";
else if (std::is_same<T, const CMyClass>::value)
std::cout << "param is a constant CMyClass\n";
else if (std::is_same<T, CMyClass>::value)
std::cout << "param is a CMyClass\n";
else
std::cout << "param is not a CMyClass\n";
}
CMyClass mc3;
func(std::move(mc3));
此小程序的输出为
param is a CMyClass
param is a CMyClass
为什么不能将mc3的类型推论为r值引用?
Why has the type of mc3 not been deduced to be an r-value reference please?
我找不到
以下项的扣除规则:
template <class T>
void foo(T&& )
在通话中 foo(expr)
是:
- 如果
expr
是类型U
的左值,然后T
推导为U&
和类型T&
是U&
,这是因为引用崩溃了。 - 如果
expr
是类型为U
的右值,则T
推导为U
,类型T& code>为
U&
,由于引用崩溃。
- If
expr
is an lvalue of typeU
, thenT
is deduced asU&
and the typeT&&
isU&
, due to reference collapsing. - If
expr
is an rvalue of typeU
, thenT
is deduced asU
the typeT&&
isU&&
, due to reference collapsing.
在您的示例中, std :: move(mc3)
是 CMyClass
类型的右值(特别是xvalue)。因此,将 T
推导为 CMyClass
。此检查:
In your example, std::move(mc3)
is an rvalue (specifically an xvalue) of type CMyClass
. Hence, T
is deduced as CMyClass
. This check:
else if (std::is_same<T, CMyClass&&>::value)
std::cout << "param is a CMyClass r-value reference\n";
几乎不会像 T
那样真实。从不推论为右值引用类型。可以这样具体提供:
will almost never be true as T
will never deduce as an rvalue reference type. It could be specifically provided as such:
func<CMyClass&&>(std::move(mc3));
但这是不太可能的用法。相反,您可以做的是检查:
but that's an unlikely usage. What you can do instead is check:
else if (std::is_same<T&&, CMyClass&&>::value)
// ~~~~
该参数是一个右值。确实,如果您只需要经常检查 T&
,就可以正确处理所有情况。
That will handle all cases where the argument is an rvalue. Indeed, if you simply always check for T&&
, that will handle all of your cases properly.