面试题答案
一键面试- 模板函数作用解释:
template <typename T> auto func(T t) -> decltype(t + 1) { return t + 1; }
:- 这个函数模板适用于那些支持与整数
1
相加操作的类型T
。decltype(t + 1)
用于推导函数的返回类型,它返回t
与1
相加后的类型。例如,如果t
是int
类型,返回类型就是int
;如果t
是double
类型,返回类型就是double
。
- 这个函数模板适用于那些支持与整数
template <typename T> std::enable_if_t<!std::is_integral_v<T>, void> func(T t) { /* 空实现 */ }
:- 这个函数模板使用了
std::enable_if
元函数。std::is_integral_v<T>
用于判断类型T
是否为整数类型。std::enable_if_t<!std::is_integral_v<T>, void>
表示当T
不是整数类型时,这个模板才是有效的。如果T
是整数类型,这个模板会被从候选函数集中排除(根据 SFINAE 原则)。此函数实现为空,它主要用于处理非整数类型的情况,虽然当前为空实现,但可以在其中添加对非整数类型的特定处理逻辑。
- 这个函数模板使用了
- 类型参数替换过程遵循 SFINAE 原则的分析:
- 调用
func(5)
时:- 首先,对于第一个模板
template <typename T> auto func(T t) -> decltype(t + 1) { return t + 1; }
,当T
被替换为int
(因为实参5
是int
类型)时,decltype(5 + 1)
是有效的,推导返回类型为int
,此模板函数是有效的候选函数。 - 对于第二个模板
template <typename T> std::enable_if_t<!std::is_integral_v<T>, void> func(T t) { /* 空实现 */ }
,当T
被替换为int
时,std::is_integral_v<int>
为true
,那么!std::is_integral_v<int>
为false
。根据std::enable_if
的规则,当条件为false
时,这个模板函数从候选函数集中被排除(SFINAE 原则)。所以最终调用的是第一个模板函数func(T t) -> decltype(t + 1)
,返回6
(因为5 + 1 = 6
)。
- 首先,对于第一个模板
- 调用
func(5.5)
时:- 对于第一个模板
template <typename T> auto func(T t) -> decltype(t + 1) { return t + 1; }
,当T
被替换为double
(因为实参5.5
是double
类型)时,decltype(5.5 + 1)
是有效的,推导返回类型为double
,此模板函数是有效的候选函数。 - 对于第二个模板
template <typename T> std::enable_if_t<!std::is_integral_v<T>, void> func(T t) { /* 空实现 */ }
,当T
被替换为double
时,std::is_integral_v<double>
为false
,那么!std::is_integral_v<double>
为true
。所以这个模板函数也是有效的候选函数。由于两个模板函数对于double
类型都是有效的,但是第一个模板函数有实际的返回值且更具体(因为第二个是空实现),编译器会选择第一个模板函数func(T t) -> decltype(t + 1)
,返回6.5
(因为5.5 + 1 = 6.5
)。
- 对于第一个模板
- 调用