问题描述
请考虑以下代码:
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& 为 U& ,由于引用崩溃。
- If expr is an lvalue of type U, then T is deduced as U& and the type T&& is U&, due to reference collapsing.
- If expr is an rvalue of type U, then T is deduced as U the type T&& is U&&, 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.
这篇关于类型不推论为r值引用:为什么不呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!