remove_reference如何禁用模板参数扣除?

Kap*_*pil 6 c++ templates perfect-forwarding c++11

根据这个链接,模板参数演绎不允许std::forward并且std::remove_reference正在帮助我们实现这一点.但是如何使用remove_reference防止模板扣除在这里发生?

template <class S>
S&& forward(typename std::remove_reference<S>::type& t) noexcept
{
    return static_cast<S&&>(t);
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 6

S在表达式typename std::remove_reference<S>::type是非推导的上下文(特别是因为S出现在使用qualified-id 指定的类型的嵌套名称说明符中).正如其名称所示,非推导的上下文是无法推导出模板参数的上下文.

这个案例提供了一个简单的例子来理解原因.说我有:

int i;
forward(i);
Run Code Online (Sandbox Code Playgroud)

S是什么?它可以是int,, int&int&&- 所有这些类型都会为函数生成正确的参数类型.这是根本不可能的编译器,以确定哪些 S你真的是在这里-所以它不会尝试.它是不可推断的,所以你必须明确提供S你的意思:

forward<int&>(i); // oh, got it, you meant S=int&
Run Code Online (Sandbox Code Playgroud)