但事实上这样的写法并不能通过编译。这是因为在编译器读到 decltype(x+y) 时,x 和 y 尚未被定义。为了解决这个问题,C++11 还引入了一个叫做尾返回类型(trailing return type),利用 auto 关键字将返回类型后置:
1 2 3 4
template<typename T, typename U> auto add2(T x, U y) -> decltype(x+y){ return x + y; }
令人欣慰的是从 C++14 开始是可以直接让普通函数具备返回值推导,因此下面的写法变得合法:
1 2 3 4
template<typename T, typename U> auto add3(T x, U y){ return x + y; }
可以检查一下类型推导是否正确:
1 2 3 4 5 6 7 8 9 10
// after c++11 auto w = add2<int, double>(1, 2.0); if (std::is_same<decltype(w), double>::value) { std::cout << "w is double: "; } std::cout << w << std::endl;
// after c++14 auto q = add3<double, int>(1.0, 2); std::cout << "q: " << q << std::endl;
template<typename R, typename T, typename U> R sub(T a, U b){ return a - b; }
template<typename T, typename U> autoadd2(T a, U b) -> decltype(a + b){ return a + b; }
template<typename T, typename U> autoadd3(T a, U b){ return a + b; }
g++将报错如下:
1 2 3 4 5
james@james-virtual-machine:~/C++/vscode/modernC++$ g++ autoKey2.cpp -std=c++20 autoKey2.cpp: In function ‘int main()’: autoKey2.cpp:29:27: error: use of ‘auto add3(T, U) [with T = int; U = int]’ before deduction of ‘auto’ 29 | cout << add3<int, int>(5, 5) << " add3(int, int)\n"; | ~~~~~~~~~~~~~~^~~~~~