网站建设服务器租用多少钱,江门免费网站建站模板,福州短视频seo推荐,免保证金入驻电商平台替换失败并不是一个错误#xff08;SFINAE#xff09; SFINAE是一个英文简称#xff0c;全称为Substitution Failure is not an Error#xff0c;翻译成中文就是“替换失败并不是一个错误”。 SFINAE可以看作C语言的一种特性或模板设计中要遵循的一个重要原则#xff0c;…替换失败并不是一个错误SFINAE SFINAE是一个英文简称全称为Substitution Failure is not an Error翻译成中文就是“替换失败并不是一个错误”。 SFINAE可以看作C语言的一种特性或模板设计中要遵循的一个重要原则非常重要务必要理解好。 这个特性显然还是针对函数模板的重载而言的。例如前面代码中既有对myfunc()函数的实现又有对myfunc()函数模板的实现那么当调用myfunc()时编译器如何选择呢编译器首先必须要针对函数模板确定哪些具体的模板参数比较合适。例如调用myfunc(15);时对于myfunc()函数模板编译器会认为类型模板参数T应该为int类型才比较合适此时编译器就会用int这个类型替换myfunc()函数模板中的T替换完毕之后编译器会根据一套自己内部的规则判断到底是调用myfunc()函数模板合适还是调用myfunc()函数合适。总之编译器最终的目的就是看调用谁合适是函数还是函数模板。 但是对于函数模板当用一个具体类型替换模板参数时可能会产生意想不到的问题如产生一些毫无意义的甚至是看起来语法上错误的代码对于这些代码编译器的处理方法并不一定是报错有可能是忽略编译器认为这个函数模板不匹配针对本次的函数调用就当这个函数模板不存在一样想象去机场接某个客人接机者会根据样貌分辨客人发现样貌不像的会直接忽略此人转而去选择其他更匹配的函数或函数模板。这就是所谓的“替换失败并不是一个错误”这个说法的由来。看一个范例首先写一个名为mydouble()的函数模板 为什么是这种错误呢不难想象当调用mydouble()的时候因为传入的是一个数字15所以编译器认为15是int类型比较合适于是编译器就会用int替换mydouble()函数模板中的T。一般来说编译器做这个替换只会替换函数模板的声明部分函数体部分编译器不会去替换替换之后大概mydouble()函数模板的声明部分就应该如下。
int::size_type mydouble(const int t);这个语法显然是错误的要是直接写这行代码编译器会报如下错误
size_type: 不是global namespace’的成员
但是因为这里编译器只是尝试用int类型替换mydouble()函数模板得到的结果代码所以编译器其实并不认为mydouble()函数模板有错这就是所谓的“替换失败并不是一个错误”替换失败就失败了对于int类型并不存在size_type成员那没准对于其他类型就存在size_type成员呢但为什么报“mydouble”:未找到匹配的重载函数的错误呢这是因为在main()主函数中对mydouble()进行调用的时候mydouble()这个函数模板不合适但又找不到其他适合调用的mydouble()所以编译器才会报这个错误。要解决这个报错问题提供一个适合调用的mydouble()函数就可以了增加如下mydouble()函数
#include killCmake.husing namespace std;templatetypename T
typename T::size_type my_double(const T t)
{return t[0] * 2;
}int my_double(int i)
{return i * 2;
}int main()
{my_double(15);return 0;
}这样mydouble(15);代码行就会直接调用mydouble()函数。如果在main()主函数中添加代码
#include killCmake.h#include vector
using namespace std;templatetypename T
typename T::size_type my_double(const T t)
{return t[0] * 2;
}int my_double(int i)
{return i * 2;
}int main()
{// error C2672: “my_double”: 未找到匹配的重载函数my_double(15);std::vectorint my_vec;my_vec.push_back(15);std::cout my_double(my_vec) std::endl;return 0;
} 上述代码调用的就是mydouble()函数模板。总结一下SFINAE的特性我编译器虽然看不出你实例化了的模板的对错错误一般指无效的类型、无效的表达式等但是我能决定是否选择你当我觉得不合适的时候我虽然不说你错但我会忽略你而不会选择你。