在完美转发中,std::forward用于转换命名的右值引用t1和t2未命名的右值引用.这样做的目的是什么?inner如果我们离开t1&t2作为左值,那将如何影响被调用的函数?
template <typename T1, typename T2>
void outer(T1&& t1, T2&& t2)
{
inner(std::forward<T1>(t1), std::forward<T2>(t2));
}
Run Code Online (Sandbox Code Playgroud) 考虑这个简单(坏)函数模板,该站点上存在许多变体:
template <typename R, typename... Args>
R call_with(std::function<R(Args...)> f,
Args... args)
{
return f(args...);
}
Run Code Online (Sandbox Code Playgroud)
两次尝试称它为:
call_with([]{}); // (a)
call_with<void>([]{}); // (b)
Run Code Online (Sandbox Code Playgroud)
我不能打电话,(a)因为lambda不是std::function<R(Args...)>这样的模板演绎失败.直截了当.
但是,(b)也失败了.我怀疑这是因为编译器无法确定我的意思是提供我所提供的所有类型参数和原因R- 因此它正在尝试(并且失败)推断出Args...初始调用失败的相同原因.
有没有办法明确指定我提供所有模板参数?为了澄清,我只对如何显式提供模板参数感兴趣,以便没有模板推导 - 我不是在寻找正确的编写方式,call_with也不是在使用lambda调用时使模板推导成功的方法.
在C++中,似乎参数通常可以...直接在参数包名称之后扩展。例如,
template <class... Tys>
void function(Tys... params) {
function(params...);
}
Run Code Online (Sandbox Code Playgroud)
然而,当使用 时std::forward,...看起来似乎在参数包名称后面。例如,
template <class... Tys>
void function(Tys... params) {
function(std::forward<Tys>(params)...); // The '...' is outside the parenthesis of 'params'
}
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么会有差异?为什么下面的代码不正确?
template<class... Tys>
void function(Tys... params) {
function(std::forward<Tys>(params...));
}
Run Code Online (Sandbox Code Playgroud)
参数包在什么时候展开?我可能不完全理解它是如何std::forward工作的或者它如何完美地转发论点。
我很感激任何答案!
c++ templates variadic-functions variadic-templates perfect-forwarding