MST

星途 面试题库

面试题:C++右值引用在模板函数参数中的应用

请编写一个模板函数,该函数接受一个右值引用参数,并在函数内部将其转发给另一个函数。请解释为什么需要使用std::forward来进行转发,以及不使用会有什么问题。
42.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>
#include <utility>

// 被调用的函数
void targetFunction(int&& value) {
    std::cout << "Target function received rvalue: " << value << std::endl;
}

// 模板函数
template<typename T>
void forwardingFunction(T&& param) {
    // 使用std::forward转发参数
    targetFunction(std::forward<T>(param));
}

使用std::forward进行转发主要是为了保持参数的原有值类别(lvalue或rvalue)。

为什么需要使用std::forward: 在模板函数中,T&&是一个万能引用,它既可以绑定到左值也可以绑定到右值。当我们需要将这个参数转发给另一个函数时,如果不使用std::forward,无论传入的是左值还是右值,在模板函数内部,这个参数都变成了一个左值(因为它有了名字)。std::forward可以根据模板参数的推导结果,在运行时决定是将参数以左值还是右值的形式转发出去,从而保证在转发过程中值类别不变。

不使用std::forward会有什么问题: 如果不使用std::forward,统一以左值形式转发参数,那么被调用函数中原本针对右值优化的重载版本将不会被调用。例如,如果targetFunction有针对左值和右值的不同重载版本:

void targetFunction(int& value) {
    std::cout << "Target function received lvalue: " << value << std::endl;
}
void targetFunction(int&& value) {
    std::cout << "Target function received rvalue: " << value << std::endl;
}

forwardingFunction中不使用std::forward,无论传入的是左值还是右值,都会调用targetFunction(int& value)这个版本,从而失去了右值引用带来的性能优化机会(如移动语义等)。