无用知识研究:在trailing return type利用decltype,comma operator在对函数进行sfinae原创 [二]
一个可以正确编译运行的例子,但并不是trailing return:
#include <iostream>template<typename T, typename std::enable_if_t<std::is_integral<T>::value,int> * = nullptr >auto foo(T)-> void
{std::cout << "I'm an integer!\n";
}template<typename T, typename std::enable_if_t<std::is_floating_point<T>::value, double>* = nullptr >
auto foo(T)-> void
{std::cout << "I'm a floating point number!\n";
}int main()
{foo(5);foo(3.4);
}运行结果:
I'm an integer!
I'm a floating point number!
一个会出现编译错误的例子,注意foo1的写法,为什么不对?:
#include <iostream>template<typename T>
auto foo1(T) ->decltype(std::is_integral<T>(), void{})
{std::cout << "I'm an integer!\n";
}template<typename T>
auto foo1(T) ->decltype(std::is_floating_point<T>(), void{})
{std::cout << "I'm a floating point number!\n";
}int main()
{foo1(5);foo1(3.4);
}编译错误信息:
C2668 “foo1”: 对重载函数的调用不明确
E0308 有多个 重载函数 "foo1" 实例与参数列表匹配: 错误点大概有:
1、void{}要改成void()
2、std::is_integral<T>()的类型,有T的替换过程(也就是substitution),对于foo1(5),
类型就是std::is_integral<int>,
也就是说第一个foo1的返回类型是(std::is_integral<int>,void),也就是void。
但没有像enable_if这样有个推导过程。
所以对于第二个foo1,按照上面的推导过程,它的返回类型也是void,没有推导,
所以才会有提示:
C2668 “foo1”: 对重载函数的调用不明确
编译信息如下,主要是foo1带来的,foo没问题:
看个正确写法的例子:
豆包搜:举一个C++的例子:在trailing return里利用decltype判断为浮点数的sfinae的例子
#include <iostream>#include <type_traits> // 包含is_floating_point和enable_if// 重载1:当T是浮点数时,此函数有效(通过SFINAE筛选)
template <typename T>
auto is_float(T value) -> decltype(// 逗号表达式:先检查enable_if的条件,再取value的类型作为返回值类型std::enable_if_t<std::is_floating_point_v<T>>(), // 若T不是浮点数,这里会替换失败value // decltype的最终结果是T(即函数返回值类型为T)) {std::cout << "类型是浮点数,值为: " << value << std::endl;return value;
}// 重载2:当T不是浮点数时,此函数有效(通过SFINAE筛选)
template <typename T>
auto is_float(T value) -> decltype(std::enable_if_t<!std::is_floating_point_v<T>>(), // 若T是浮点数,这里会替换失败value) {std::cout << "类型不是浮点数,值为: " << value << std::endl;return value;
}int main() {// 测试浮点数类型is_float(3.14f); // float(浮点数)is_float(3.14); // double(浮点数)is_float(0.0L); // long double(浮点数)// 测试非浮点数类型is_float(42); // int(非浮点数)is_float('a'); // char(非浮点数)is_float(true); // bool(非浮点数)return 0;
}