c++ - 是否可以忽略 c++11 的尾随返回类型特性而支持 c++14 的函数返回类型推导特性?

标签 c++ c++11 c++14 trailing-return-type return-type-deduction

当我跳过表达式的返回类型时

C++11中的以下代码:

auto function(X x, Y y) -> decltype(x + y)
{
    return x + y;
}

等于C++14中的如下代码:

decltype(auto) function(X x, Y y)
{
    return x + y;
}

但另外,在 C++14 中也可以在没有 decltype 规则的情况下推断返回类型:

auto function()
{
    return 0;
}

当我知道返回类型究竟是什么时

C++11中的以下代码:

auto function() -> int
{
    return 0;
}

等于C++03中的如下代码:

int function()
{
    return 0;
}

一个不应该发生的奇怪例子

C++11中的以下代码:

auto function(X x, Y y) -> decltype(x * y)
{
    return x; // Yeah! return x with the type of x * y expression!
}

等于C++14中的如下代码:

decltype(auto) function(X x, Y y)
{
    return static_cast<decltype(x * y)>(x);
}

如果上面的代码有错误并且不能按预期工作,请纠正我。

EDIT根据评论(Yakk):它们并不真正相等,第一个(C++11示例)是隐式转换而第二个(C++14 示例的 static_cast)是显式强制转换。

结论

如您所见,我可以在不使用 C++11 的 替代函数语法 特性的情况下做任何事情。我对么?我可以完全忘记它而不会遇到任何技术问题吗?

一般来说,可以避免以下语法:

auto function() -> TYPE
{
    return 0;
}

赞成以下语法:

TYPE function() // TYPE can be: auto, decltype(auto), or ...
{
    return 0;
}

我是否忘记了 C++11 的 尾随返回类型 功能的任何用法,而 C++14 的 函数返回类型推导 功能是不可能的?

最佳答案

使用自动返回类型推导的函数与使用显式返回类型(即使是计算出来的)的函数之间存在三个重要区别:

  1. 如果你没有明确指定返回类型的可计算性,你就不能对它进行 SFINAE:你会得到一个硬错误。为什么?因为 SFINAE 只适用于声明,而不适用于函数的定义(SFINAE: (template-argument) substitution-failure 不是错误)。

    automatic-return-type-deduction , 没有 SFINAE
    SFINAE ,但没有自动返回类型的扣除

    #include <iostream>
    int doit(int x, ...) { return x; }
    template<class X, class Y> auto doit(X x, Y y)
    #ifdef TRAILING_RETURN_TYPE
    -> decltype(doit(x) + doit(y))
    #endif
    { return doit(x) + doit(y); }
    
    int main() {
        std::cout << doit(1, nullptr) << "\n";
    }
    
  2. 目前,如果定义使用自动返回类型推导,您不能前向声明具有实际返回类型的函数,也不能是虚拟的。 (显式规则)

    7.1.6.4 auto specifier [dcl.spec.auto]

    13 Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall also use that placeholder, not a deduced type.
    14 A function declared with a return type that uses a placeholder type shall not be virtual (10.3).

  3. 只有具有自动返回类型推导的函数才能返回 lambda,因为没有其他方法可以获取其类型。

     auto foo() { return [] {}; }
    

该提案的链接,该提案已被纳入 C++14 草案:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html

关于c++ - 是否可以忽略 c++11 的尾随返回类型特性而支持 c++14 的函数返回类型推导特性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25341378/

相关文章:

c++ - C++ 中 vector 的 vector 的使用 & push_back( )

c++ - Intellisense 自动完成导致 Visual Studio 2005 SP1 中的 C++ 崩溃

c++ - 为什么 SFINAE 在这个简单的成员函数重载中不起作用

c++ - 为什么在这种情况下转发引用不起作用?

c++ - 混合 decltype 和 enable_if

c++ - 使用写迭代器支持在 C++ 中包装遗留 C API

C++14 将元组三乘三展开

c++ - 用于压缩的缓冲区的 zlib c++ char 大小

c++ - 是否可以检测是否声明了局部变量?

c++ - 传递一些东西作为这个参数丢弃限定符