类型不推断为r值参考:为什么不呢?

时间:2017-02-09 19:42:01

标签: c++ c++11

请考虑以下代码:

param is a CMyClass
param is a CMyClass

这个小程序的输出是

class Test {
    MatrixXf DH(6, 4);
public:
    Test() {
    }
};

为什么mc3的类型没有被推断为r值参考?

2 个答案:

答案 0 :(得分:6)

即使一个人必须存在于某个地方,我也无法找到一个好的骗局,抱歉。

以下的扣除规则:

template <class T>
void foo(T&& )
在电话foo(expr)的上下文中

是:

  • 如果exprU类型的左值,则T推断为U&,类型T&&U&,到期引用崩溃。
  • 如果exprU类型的右值,则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 ,则Tfunc内的非参考T&&右值参考。这是一个凭经验显示T在带有转发引用的函数体中的含义的示例:

template <typename T>
void func(T&& x)
{
    std::is_same<T, something>{}; // (0)
    std::is_same<T&&, something>{}; // (1)
}

如果是(0)

    rvalue 传递给T时,
  • T func。的(*)
  • 左值传递给T时,
  • T& func

(1)

的情况下
    rvalue 传递给T&&时,
  • T&& func
  • 左值传递给T&&时,
  • T& func

如果您使用std::is_same<T&&, CMyClass>::value,则应获得T&T&&

(*):请注意,术语&#34;是&#34;不准确 - T func内的T的各种含义取决于template argument deductionreference collapsing

简而言之:

  • T&推断为:

      如果x左值,则
    • T

    • T&&否则。

  • 由于引用崩溃T&为:

      如果x左值,则
    • T& &&T& - &gt; T&&

    • T&& &&否则。 T&& - &gt; {{1}})