V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
XIVN1987
V2EX  ›  C++

《Effective Modern C++》中“Item 3: Understand decltype”章节读书笔记

  •  
  •   XIVN1987 · 2021-01-20 11:54:54 +08:00 · 1503 次点击
    这是一个创建于 1163 天前的主题,其中的信息可能已经有所发展或是发生改变。

    《 Effective Modern C++》真是本好书,,讲的深入浅出,非常清晰

    decltype

    Given a name or an expression, decltype tells you the name’s or the expression’s type

    const int i = 0;            // decltype(i) is const int
    
    bool f(const Widget& w);    // decltype(w) is const Widget&
                                // decltype(f) is bool(const Widget&)
    
    template<typename T>
    class vector {
    public:
        T& operator[](std::size_t index);
    };
    vector<int> v;              // decltype(v) is vector<int>
                                // decltype(v[0]) is int&
    

    如何查看 decltype(f)、decltype(v[0])的值?

    template<typename T>
    class TD;                   // Type Displayer
    
    TD<decltype(v[0])> x;
    

    编译如上代码,编译器会报错如下:

    error: aggregate 'TD<int&> x' has incomplete type and cannot be defined
    

    由此可知 decltype(v[0])的结果是int&

    decltype(auto)

    auto specifies that the type is to be deduced, and decltype says that decltype rules should be used during the deduction

    template<typename Container, typename Index>
    decltype(auto) authAndAccess(Container& c, Index i)
    {
        authenticateUser();
        return c[i];
    }
    
    

    这里之所以使用 decltype(auto)而不是 auto,是因为绝大多数 containers-of-T 的[]运算符返回 T&,用 auto 的话会丢失&属性

    decltype((name))

    if an lvalue expression other than a name has type T, decltype reports that type as T&

    int x = 3;      // decltype(x)   is int
                    // decltype((x)) is int&
    

    注意:decltype(-x)等不会出现这种问题,因为-x等表达式都是右值,只有(x)既是表达式还是左值

    这将导致下面两个函数的返回值类型不同

    decltype(auto) f1()
    {
        int x = 0;
        return x;
    }
    
    decltype(auto) f2()
    {
        int x = 0;
        return (x);
    }
    
    5 条回复    2021-01-21 14:40:46 +08:00
    jones2000
        1
    jones2000  
       2021-01-20 12:16:20 +08:00
    这个是 c++几的特性?
    编译器要什么版本的?
    linux40
        2
    linux40  
       2021-01-20 12:23:51 +08:00
    @jones2000 decltype(auto) 这种写法起码 C++14 。
    XIVN1987
        3
    XIVN1987  
    OP
       2021-01-20 12:34:29 +08:00
    @jones2000
    C++14

    C++14 是个小升级,相对于 C++11 添加的特性不多,,
    如果能用 C++11 的话,建议用 C++14,,毕竟 C++14 里有 std::make_unique
    auto8888
        4
    auto8888  
       2021-01-20 17:05:23 +08:00
    哇撒,发现公司 gcc 版本升级到 7.5.0 了,可以玩 c++17 了,爽
    willhunger
        5
    willhunger  
       2021-01-21 14:40:46 +08:00
    可以更仔细一点:

    如果函数返回值只用 auto 的话,采用的是模板类型推导,而函数模板类型推导中如果函数形参为引用类型(非万能引用类型)的话,会忽略其 & 属性。故才需要采用 decltype(auto)。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5388 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 01:31 · PVG 09:31 · LAX 18:31 · JFK 21:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.