请考虑以下代码:
param is a CMyClass
param is a CMyClass
这个小程序的输出是
class Test {
MatrixXf DH(6, 4);
public:
Test() {
}
};
为什么mc3的类型没有被推断为r值参考?
答案 0 :(得分:6)
即使一个人必须存在于某个地方,我也无法找到一个好的骗局,抱歉。
以下的扣除规则:
template <class T>
void foo(T&& )
在电话foo(expr)
的上下文中是:
expr
是U
类型的左值,则T
推断为U&
,类型T&&
为U&
,到期引用崩溃。 expr
是U
类型的右值,则T
推断为U
类型T&&
为U&&
,原因是参考崩溃。在您的示例中,std::move(mc3)
是CMyClass
类型的右值(特别是x值)。因此,T
被推断为CMyClass
。这个检查:
else if (std::is_same<T, CMyClass&&>::value)
std::cout << "param is a CMyClass r-value reference\n";
几乎永远不会成为真,因为T
永远不会推导为右值引用类型。它可以特别提供:
func<CMyClass&&>(std::move(mc3));
但这不太可能。你可以做的是检查:
else if (std::is_same<T&&, CMyClass&&>::value)
// ~~~~
这将处理参数为右值的所有情况。实际上,如果您只是一直检查T&&
,那么这将正确处理您的所有案例。
答案 1 :(得分:3)
为什么mc3的类型没有被推断为r值参考?
如果param
是 rvalue ,则T
是func
内的非参考,T&&
是右值参考。这是一个凭经验显示T
在带有转发引用的函数体中的含义的示例:
template <typename T>
void func(T&& x)
{
std::is_same<T, something>{}; // (0)
std::is_same<T&&, something>{}; // (1)
}
如果是(0):
T
时,T
func
。的(*)强> T
时,T&
func
。在(1):
的情况下T&&
时,T&&
func
。T&&
时,T&
func
。如果您使用std::is_same<T&&, CMyClass>::value
,则应获得T&
或T&&
。
(*):请注意,术语&#34;是&#34;不准确 - T
func
内的T
的各种含义取决于template argument deduction和reference collapsing。
简而言之:
T&
推断为:
x
是左值,则 T
。
T&&
否则。
由于引用崩溃,T&
为:
x
是左值,则 T& &&
。 (T&
- &gt; T&&
)
T&& &&
否则。 (T&&
- &gt; {{1}})