面试题答案
一键面试template<typename... Args>
void func(Args&&... args) {
// 使用std::apply将参数包展开并转发给targetFunc
std::apply([](auto&&... a) { targetFunc(std::forward<decltype(a)>(a)...); }, std::make_tuple(std::forward<Args>(args)...));
}
std::forward
保证参数属性不被改变的原理
std::forward
的作用:std::forward
是一个类型转换函数,它的主要目的是在模板函数中,根据实参的原始类型,将参数以正确的左值或右值形式转发出去。- 模板参数推导:在
func
函数模板中,Args&&... args
是一个转发引用(universal reference)。当调用func
时,编译器会根据传入的实参类型来推导Args
的类型。如果传入的是左值,Args
会被推导为左值引用类型;如果传入的是右值,Args
会被推导为非引用类型。 std::forward
的实现:std::forward
通过条件判断来决定如何转换参数。如果Args
是左值引用类型,std::forward<Args>(arg)
会将arg
转换为左值;如果Args
是非引用类型,std::forward<Args>(arg)
会将arg
转换为右值。这样就保证了参数在转发过程中其左值或右值属性不被改变。
确保func
能够正确转发到合适的重载版本
- 重载决议规则:C++的重载决议机制会根据函数调用时实参的类型来选择最合适的重载版本。在
func
函数中,通过std::forward
将参数以正确的类型转发给targetFunc
,这样targetFunc
的重载决议就会基于原始实参的类型来进行。 - 示例:如果
targetFunc
有多个重载版本,例如:
void targetFunc(int, double, std::string);
void targetFunc(int, double, int);
当调用func
时,只要func
中的参数转发使用了std::forward
,编译器就会根据传入func
的实参类型,正确地将调用转发到合适的targetFunc
重载版本。例如:
func(1, 2.0, std::string("hello")); // 会转发到void targetFunc(int, double, std::string)
func(1, 2.0, 3); // 会转发到void targetFunc(int, double, int)
编译器会根据func
调用时实参的类型,在targetFunc
的多个重载版本中做出正确选择。