remove_reference 如何禁用模板参数推导?

How remove_reference disable template argument deductions?

根据 this linkstd::forward 不允许模板参数推导,std::remove_reference 正在帮助我们实现这一点。但是使用 remove_reference 如何防止模板推导发生在这里呢?

template <class S>
S&& forward(typename std::remove_reference<S>::type& t) noexcept
{
    return static_cast<S&&>(t);
}
表达式 typename std::remove_reference<S>::type 中的

S 非推导上下文 (特别是因为 S 出现在 使用 qualified-id 指定类型的嵌套名称说明符)。非推导上下文,顾名思义,就是无法推导模板参数的上下文。

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

int i;
forward(i);

S 会是什么?它可以是 intint&int&& - 所有这些类型都会为函数产生正确的参数类型。编译器根本不可能确定 which S 你真正的意思 - 所以它不会尝试。它是不可推导的,因此您必须明确提供您的意思 S

forward<int&>(i); // oh, got it, you meant S=int&