本文介绍了是否可以忽略c ++ 11的尾随返回类型特征,有利于c ++ 14的函数返回类型推导特征?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

跳过表达式的返回类型



C ++ 11 中的以下代码:

 自动功能(X x,Y y) - > decltype(x + y)
{
return x + y;
}

等于 C ++ 14

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

但是另外还可以推导出返回类型,不带 中的 > decltype 规则:


{
return 0;
}



当我知道返回类型是什么



C ++ 11 中的以下代码:

 自动功能() - > int 
{
return 0;
}

等于 C ++ 03

  int function()
{
return 0;
}



一个奇怪的例子,永远不会发生



C ++ 11 中的以下代码:

 自动函数x,Y y) decltype(x * y)
{
return x; //是啊!返回x与x * y表达式的类型!
}

等于 C ++ 14

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

请更正我,如果上述代码错误,

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



结论



正如你所看到的, em>> C ++ 11的替代函数语法特性。我对么?



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

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

赞成下列语法:

  TYPE函数()// TYPE可以是:auto,decltype(auto)或... 
{
return 0;
}

我忘记了任何使用结尾返回类型函数返回类型推导功能不可能实现C ++ 11的特性?

解决方案

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


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



    ,no 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 }
    int main(){
    std :: cout<< doit(1,nullptr)<< std :: endl;
    }


  2. 目前,您无法使用实际返回类型,如果定义使用自动返回类型扣除,也不能是虚拟的。 (显式规则)


  3. 只有具有自动返回类型扣除的函数可以返回一个lambda,因为没有其他方法来获取它的类型。

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


链接到提案转换为C ++ 1y的草稿:


When I skip the return type of an expression

The following code in C++11:

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

Is equal to the following code in C++14:

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

But additionally it is possible to deduce the return type without decltype rules in C++14:

auto function()
{
    return 0;
}

When I know what the return type is exactly

The following code in C++11:

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

Is equal to the following code in C++03:

int function()
{
    return 0;
}

A strange example that should never happen

The following code in C++11:

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

Is equal to the following code in C++14:

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

Please correct me, if the above code is wrong and does not work as expected.

EDIT, According to the comment (Yakk): They are not really equal, the first one (C++11 example) is an implicit cast while the second one (the static_cast of C++14 example) is an explicit cast.

Conclusion

As you can see, I can do everything without using the alternative function syntax feature of C++11. Am I correct? Can I completely forget about it without getting any technical problem?

In general, the following syntax can be avoided:

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

In favor of the following syntax:

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

Did I forget any usage of the trailing return type feature of C++11 that is not possible with the function return type deduction feature of C++14?

解决方案

There are three important differences between a function using automatic-return-type-deduction and one with an explicit return-type (even if that is computed):

  1. You cannot do SFINAE on the computability of the return-type if you do not explicitly specify it: You get a hard error instead. Why? Because SFINAE only works with the declaration, not the definition of functions (SFINAE: (template-argument) substitution-failure is not an error).

    automatic-return-type-deduction, no SFINAE
    SFINAE, but no automatic return-type deduction

    #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) << std::endl;
    }
    

  2. At the moment, you cannot forward-declare a function with its actual return-type, if the definition uses automatic return-type-deduction, nor can it be virtual. (Explicit rule)

  3. Only functions with automatic return-type deduction can return a lambda, as there is no other way to get its type.

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

Link to the proposal, which was incorporated into the draft for C++1y:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html

这篇关于是否可以忽略c ++ 11的尾随返回类型特征,有利于c ++ 14的函数返回类型推导特征?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 02:05