c++ - 将函数引用作为通用引用传递

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

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

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]

这是完全可以理解的:我们将左值传递给我们的函数 foo,因此推导的类型是 void(&)int,并且参数的类型将是“void(&& &)int”,在引用折叠规则下它变成无效(&)整数。 Param 将只是函数的左值引用。

但是当我执行以下操作时:

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

foo 将打印:

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

和之前一模一样!这里发生了什么?为什么结果与传递左值时的结果相同?我希望因为我们将右值传递给 foo,推导的类型应该是 T = void(int),并且 param 应该变成 void(&&)int。这总是发生在所有其他“正常”类型(如类、原始类型等)上。为什么在处理函数引用时会有所不同?

最佳答案

A std::move是一个荣耀static_cast右值引用类型。该标准表示转换为函数类型的右值引用仍然会产生左值。根据 [expr.static.cast]/p1:

The result of the expression static_cast<T>(v) is the result of converting the expression v to type T. If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue;

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

A function call is an lvalue if the result type is an lvalue reference type or an rvalue reference to function type, an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise.

关于c++ - 将函数引用作为通用引用传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31125447/

相关文章:

c++ - 在函数内调用 "continue"

c++ - 用不同的值初始化 const 容器的正确方法是什么?

c++ - 为 vardiac 和 normal 模板设置 typename 默认值

multithreading - 在等待通知std::condition_variable的过程中执行 “wait callback”

C++构造函数中的通用引用和返回值优化(rvo)

c++ - 覆盖抽象类的属性

c++ - 模板化 "Listener"处理程序歧义问题

c++ - 如何在 Windows 上使用 Visual C++ 强制加载链接库

c++ - 等效的 static_asserts 给出了 is_array<> 的冲突结果

c++ - 通用引用产生具有相同地址的不同实例