template<typenameU>Tadd(Ux)const{ifconstexpr(std::is_same<T,std::vector<U>>::value){autocopy(val);for(auto&n : copy){ n += x;}return copy;}else{return val + x;}}
addable<int>{1}.add(2);// is 3addable<float>{1.f}.add(2);// is 3.0addable<std::string>{"aa"}.add("bb");// is "aabb"std::vector<int> v{1,2,3};addable<std::vector<int>>{v}.add(10);// is std::vector<int> {11, 12, 13}std::vector<std::string> sv{"a","b","c"};addable<std::vector<std::string>>{sv}.add(std::string{"z"});// is {"az", "bz", "cz"}
当编译器看到具有相同名称的不同模板函数并不得不选择其中一个时,一个重要的原则就起作用了:替换失败不是错误(SFINAE, Substitution Failure is not An Error)。这个例子中,就意味着如果函数的返回值来源一个错误的模板表示,无法推断得出,这时编译器不会将这种情况视为错误(和std::enable_if中的条件为false时的状态一样)。这样编译器就会去找函数的另外的实现。