将引用函数作为通用引用传递

时间:2015-06-29 20:58:36

标签: c++ c++11 universal-reference

我很难理解将函数引用作为通用引用传递给函数时究竟发生了什么(正在推导出什么类型)。让我们假设我们有一个函数foo,它将param作为通用引用:

template<typename T>
void foo(T&& param)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

然后让我们执行以下操作:

void(&f)(int) = someFunction;
foo(f);

结果将是:

void foo(T&&) [with T = void (&)int]

这是完全可以理解的:我们将lvalue传递给我们的函数foo,因此推导出的类型是void(&amp;)int,而param的类型将是&#34; void(&amp;&amp;&amp;) INT&#34;根据参考折叠规则变为无效(&amp;)int。 Param只是函数的左值引用。

但是当我做以下事情时:

void(&f)(int) = someFunction;
foo(std::move(f));

foo将打印:

void foo(T&&) [with T = void (&)int]

与以前完全一样!这里发生了什么?为什么结果与传递左值相同?我希望由于我们将rvalue传递给foo,推导出的类型应该是T = void(int),而param应该变为void(&amp;&amp;)int。这总是发生在所有其他&#34;正常&#34;类型(如类,基元类型等​​)为什么在处理函数引用时会有所不同?

1 个答案:

答案 0 :(得分:6)

std::move是一个美化static_cast到右值的参考类型。标准说,转换为函数类型的右值引用仍会产生左值。 Per [expr.static.cast] / p1:

  

表达式static_cast<T>(v)的结果是将表达式v转换为类型T的结果。 如果T是左值引用类型或函数类型的右值引用,则结果为左值;

关于std::move()函数调用的值类别,它返回一个指定转换结果的右值引用,我们也可以从[expr.call] / p10看到一个函数调用是一个左值,如果它return类型是函数类型的右值引用:

  

如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值,如果结果类型是右值引用,则为xvalue对象类型,否则为prvalue。