#include <iostream>
#include <type_traits>
#include <string>
template <typename T,
typename = std::enable_if_t<!std::is_same_v<T, std::string>>>
void func(T t) {
std::cout << "func called with non - std::string type" << std::endl;
}
// 测试
int main() {
func(10);
func(3.14f);
// func(std::string("test")); // 这行代码会导致编译错误
return 0;
}
SFINAE 工作原理解释
std::enable_if
:这是 SFINAE 机制中的关键工具。std::enable_if
是一个类型特性模板,它接受两个参数,第一个是一个布尔值,第二个是一个默认类型(通常为 void
)。
- 条件判断:
std::is_same_v<T, std::string>
用于判断类型 T
是否为 std::string
。std::enable_if_t<!std::is_same_v<T, std::string>>
表示当 T
不是 std::string
类型时,std::enable_if
的第一个模板参数为 true
,此时 std::enable_if
的第二个模板参数(即 void
)会被推导出来。
- 函数模板重载决议:在函数模板重载决议过程中,如果某个函数模板的模板参数推导不出来(例如
T
为 std::string
时,std::enable_if_t<!std::is_same_v<T, std::string>>
无法推导出类型,因为条件为 false
),那么这个函数模板就不会参与重载决议,就好像这个函数模板不存在一样,从而实现了排除 std::string
类型的目的。