inq*_*uam 5 c++ decltype c++11 trailing-return-type
我正在阅读一篇有关“新”C++ 功能的文本,并遇到了decltype及其用法。我理解尾随返回类型中decltype背后的推理,例如
template <typename lhsT, typename rhsT>
auto add(lhsT& lhs, rhsT& rhs) -> decltype(lhs + rhs) {
return lhs +rhs;
}
Run Code Online (Sandbox Code Playgroud)
如果没有它,编译器将无法导出模板函数的返回类型。但为什么语法是这样的呢?
为什么不使用类似的东西
template <typename lhsT, typename rhsT>
decltype(lhs + rhs) add(lhsT& lhs, rhsT& rhs) {
return lhs +rhs;
}
Run Code Online (Sandbox Code Playgroud)
感觉更“自然”,因为返回类型是在通常的位置声明的,尽管是两个参数的结果。这是否与其他内容发生冲突,或者如果语法是这种不值得的方式,它是否会给编译器带来额外的工作?
\n\n\n如果没有它,编译器将无法导出模板函数的返回类型。
\n
后来在 C++14 中修复了这个问题,编译器不需要尾随返回类型,因为它可以从返回的表达式推断返回类型。以下内容在 C++14 中运行良好。
\n\ntemplate <typename lhsT, typename rhsT>\nauto add(const lhsT& lhs, const rhsT& rhs) {\n return lhs + rhs;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n\n但为什么语法是这样的呢?
\n
当从参数推导返回类型时,使用尾随返回类型非常有用,参数总是在返回类型之后声明(不能引用尚未声明的内容)。
\n\n此外,从函数和数学符号使用这种声明的意义上来说,尾随返回类型确实看起来更自然。我认为 C 风格声明之外的大多数表示法类型通常都使用尾随返回类型。例如:
\n\n\n\n\nf : X \xe2\x86\x92 Y
\n
在上面的数学符号中,f
是函数名、X
参数和Y
返回值。
仅仅因为粉红色的羊群拒绝灰色的羊并不意味着它不自然。
\n\n在您的第二个示例中,编译器不可能根据上述原因推断返回类型,即参数尚未声明。但是,如果使用模板参数 和 ,则可以进行推断std::declval
,例如:
template <typename T, typename U>\ndecltype(std::declval<T>() + std::declval<U>()) add(const T& lhs, const U& rhs) {\n return lhs + rhs;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\nstd::declval
充当类型的惰性实例化并且从不计算,例如,调用构造函数等。它主要在推断类型时使用。