remove_reference 如何禁用模板参数推导?
How remove_reference disable template argument deductions?
根据 this link,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);
}
表达式 typename std::remove_reference<S>::type
中的 S
是 非推导上下文 (特别是因为 S
出现在 使用 qualified-id 指定类型的嵌套名称说明符)。非推导上下文,顾名思义,就是无法推导模板参数的上下文。
这个案例提供了一个简单的例子来理解原因。假设我有:
int i;
forward(i);
S
会是什么?它可以是 int
、int&
或 int&&
- 所有这些类型都会为函数产生正确的参数类型。编译器根本不可能确定 which S
你真正的意思 - 所以它不会尝试。它是不可推导的,因此您必须明确提供您的意思 S
:
forward<int&>(i); // oh, got it, you meant S=int&
根据 this link,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);
}
typename std::remove_reference<S>::type
中的 S
是 非推导上下文 (特别是因为 S
出现在 使用 qualified-id 指定类型的嵌套名称说明符)。非推导上下文,顾名思义,就是无法推导模板参数的上下文。
这个案例提供了一个简单的例子来理解原因。假设我有:
int i;
forward(i);
S
会是什么?它可以是 int
、int&
或 int&&
- 所有这些类型都会为函数产生正确的参数类型。编译器根本不可能确定 which S
你真正的意思 - 所以它不会尝试。它是不可推导的,因此您必须明确提供您的意思 S
:
forward<int&>(i); // oh, got it, you meant S=int&