完美转发可以将函数参数以原始的形式转发给另一个函数,而不会丢失任何信息或进行不必要的拷贝。

完美转发通常用在函数模板中传递参数,在函数模板中,参数的类型和数量是不确定的,因此需要使用完美转发来讲参数以原始的形式传递给其他函数。

#include <iostream>
#include <utility>

void print(int& x) {
    std::cout << "lvalue" << std::endl;
}

void print(int&& x) {
    std::cout << "rvalue" << std::endl;
}

template<typename T>
void forwarder(T&& arg) {
    print(std::forward<T>(arg));
}

int main() {
    int x = 42;
    forwarder(x);
    forwarder(123);
    return 0;
}

在这个示例代码中,我们定义了两个名为 print 的函数,一个接受左值引用类型的参数,另一个接受右值引用类型的参数。然后,我们定义了一个名为 forwarder 的函数模板,它接受一个任意类型的参数 arg

std::forward 函数可以根据参数的类型来选择将其转发为左值引用或右值引用。这可以确保参数以原始的形式传递给其他函数,而不会丢失任何信息或进行不必要的拷贝

关于完美转发可能还涉及到下面的万能引用的知识点:

下面的是深入理解c++11中给出的demo:

#include <iostream>
using namespace std;
void RunCode(int && m) { cout << "rvalue ref" << endl; }
void RunCode(int & m) { cout << "lvalue ref" << endl; }
void RunCode(const int && m) { cout << "const rvalue ref" << endl; }
void RunCode(const int & m) { cout << "const lvalue ref" << endl; }
template <typename T>
void PerfectForward(T &&t) {    RunCode(forward<T>(t));     }
int main() {
    int a;
    int b;
    const int c = 1;
    const int d = 0;
    PerfectForward(a);             // lvalue ref
    PerfectForward(move(b));     // rvalue ref
    PerfectForward(c);             // const lvalue ref
    PerfectForward(move(d));     // const rvalue ref
}
// 编译选项:g++ -std=c++11 3-3-9.cpp

运行以上代码,输出将是:

lvalue ref
rvalue ref
const lvalue ref
const rvalue ref

  1. 完美转发:通过使用通用引用类型并结合 forward 函数,在模板函数中能够完美地将参数转发给其他函数,保持参数的左值或右值特性。
  2. 引用折叠:在模板类型推断过程中,根据引用折叠规则,将引用类型折叠为一个已知的简单表达式。这样可以处理各种类型的参数,并调用正确的函数重载版本。
  3. 移动语义:通过使用 move 函数,可以将左值转换为右值引用,从而实现移动语义,避免不必要的拷贝操作。