【问题标题】:Is it possible to ignore the trailing return type feature of c++11 in favor of the function return type deduction feature of c++14?是否可以忽略 c++11 的尾随返回类型特性而支持 c++14 的函数返回类型推导特性?
【发布时间】:2014-10-10 01:43:56
【问题描述】:

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

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 的 函数返回类型推导 特性是不可能的?

【问题讨论】:

  • SFINAE!!?我没听说过!现在应该搜索它:-D
  • static_cast 不是隐式转换。它可以更强大。例如,如果x*y返回类型Q*,如果U*类型返回X,并且QU的派生类,那么auto function(X x, Y y) -&gt; decltype(x*y) { return x; }不同于auto function( X x, Y y ) { return static_cast&lt;decltype(x*y)&gt;(x); }——一个编译,另一个不编译。

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


【解决方案1】:

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

  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 自动说明符[dcl.spec.auto]

    13 具有使用占位符类型的已声明返回类型的函数或函数模板的重新声明或特化也应使用该占位符,而不是推导类型。
    14 使用占位符类型的返回类型声明的函数不应是虚拟的 (10.3)。

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

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

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

【讨论】:

  • 不错的改进 =D(有时会重复帮助)
  • @pepper_chico 是的,他们有帮助 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 2019-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多