一个可以正确编译运行的例子,但并不是trailing return:
cpp
#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的写法,为什么不对?:
cpp
#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的例子
cpp
#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;
}