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

2021-01-20 11:54:54 +08:00
 XIVN1987

《 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);
}
1538 次点击
所在节点    C++
5 条回复
jones2000
2021-01-20 12:16:20 +08:00
这个是 c++几的特性?
编译器要什么版本的?
linux40
2021-01-20 12:23:51 +08:00
@jones2000 decltype(auto) 这种写法起码 C++14 。
XIVN1987
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
2021-01-20 17:05:23 +08:00
哇撒,发现公司 gcc 版本升级到 7.5.0 了,可以玩 c++17 了,爽
willhunger
2021-01-21 14:40:46 +08:00
可以更仔细一点:

如果函数返回值只用 auto 的话,采用的是模板类型推导,而函数模板类型推导中如果函数形参为引用类型(非万能引用类型)的话,会忽略其 & 属性。故才需要采用 decltype(auto)。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/746632

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX