【问题标题】:Why decltype is used in trailing return types?为什么 decltype 用于尾随返回类型?
【发布时间】:2023-03-04 20:47:01
【问题描述】:

考虑以下代码:

template< class T1 , class T2>
auto calc( T1 a , T2 b )
{
   return a + b ;
}


template< class T1 , class T2>
auto calc( T1 a , T2 b ) -> decltype( a + b )
{
   return a + b ;
}

第二个代码有什么区别? 你能举一些例子说明这会有所不同还是在这里有所作为?

【问题讨论】:

    标签: c++ c++11 auto decltype return-type-deduction


    【解决方案1】:

    请注意,普通的 auto 返回类型仅适用于 C++14,而带有 decltype 的尾随返回类型适用于 C++11。当参考进入图片时,差异就出现了,例如在这样的代码中:

    #include <type_traits>
    
    struct Test
    {
        int& data;
    
        auto calc1()
        {
           return data;
        }
    
        auto calc2() -> decltype(data)
        {
           return data;
        }
    };
    
    int main()
    {
        int x;
        Test t{x};
        static_assert(std::is_same<int, decltype(t.calc1())>::value, "");
        static_assert(std::is_same<int&, decltype(t.calc2())>::value, "");
    }
    

    如果您想删除 -&gt;decltype() 并保持代码行为相同,可以使用 C++14 构造 decltype(auto)

    decltype(auto) calc3() // same as calc2() above
    {
        return data;
    }
    

    这也保留了返回类型的引用性。

    如果你已经知道你的返回类型是一个引用,那就明确说明

    auto& calc4() // same as calc2() above
    {
        return data;
    }
    

    【讨论】:

    • 感谢您回答 Rex :) 好的,所以除了保留参考之外,两者都是相同的。那么应该使用哪一种或使用哪一种更安全?
    • 这取决于你想要什么。我会使用autoauto&amp; 来明确返回类型的引用性是什么。有时decltype 可以有它的优势,例如在您想要延迟实例化等的 SFINAE 上下文中。But that's advanced stuff.
    • decltype(auto) 有时可能很危险。例如: decltype(auto) foo () { auto x = 5;返回(x);因为 (x) 是一个表达式,is type 是 int& (很多人围绕返回这个括号)。所以这个函数返回一个对本地的引用,这是一个bug!
    • @MinasMina 是的,没错,一次应该只对返回 *this; 的类成员类型的 operator[] 执行此操作,并且永远不会对函数局部变量执行此操作
    猜你喜欢
    • 2011-11-07
    • 2017-08-02
    • 2019-01-26
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多