C++标准14.8.2 $ 7说:替代在模板参数推演中如何工作?
取代在所有类型和表达了在函数类型并在模板参数声明使用发生。这些表达式不仅包括常量表达式,例如出现在数组边界或非类型模板参数中的常量表达式,还包括
sizeof
,decltype
以及允许非常量表达式的其他上下文中的常规表达式(即非常量表达式)。替换按词汇顺序进行,并在遇到导致扣除失败的条件时停止。 [注意:异常规范中的等价替换只有在例外规范被实例化时才能完成,在这种情况下,如果替换导致无效类型或表达式,则程序不合格。 - 注完]
这里的标准提供了一个例子:
template <class T> struct A { using X = typename T::X; };
template <class T> typename T::X f(typename A<T>::X);
template <class T> void f(...) { }
template <class T> auto g(typename A<T>::X) -> typename T::X;
template <class T> void g(...) { }
void h() {
f<int>(0); // OK, substituting return type causes deduction to fail
g<int>(0); // error, substituting parameter type instantiates A<int>
}
为什么叫g<int>(0)
是错误的吗?尾随返回类型T::X
是否导致替换失败?模板功能f
和g
之间有什么区别?
返回类型如何作为函数签名的一部分而不是参数? – Barry
@Barry我认为返回类型和参数都被认为是函数签名的一部分 – Carousel
@Barry它们都是函数模板签名的一部分,但我可能不应该在这里使用“签名”。 –