[effective modern c++][5]与其使用显示类型推断不如使用auto

优势

防止忘记初始化变量

int x1;         // 忘记初始化
auto x2;        // error
auto x3 = 0;    // correct

防止写过长的显示类型

template<typename It>
void dwim(It b, It e) {
    while (b != e) {
        typename std::iterator_traits<It>::value_type curr_value = *b;
        ...
    }
}

template<typename It>
void dwim(It b, It e) {
    while (b != e) {
        auto curr_value = *b;
        ...
    }
}

表示只有编译器才知道的类型

// C++11
auto derefUPLess = [](const std::unique_ptr<Widget>& p1,
        const std::unique_ptr<Widget>& p2) {return *p1 < *p2;};
// C++14
auto derefUPLess = [](const auto& p1, const auto& p2) {return *p1 < *p2;};

在 C++11 中,使用 std::function对象也可以表示这个类型

std::function<bool(const std::unique_ptr<Widget>&,
        const std::unique_ptr<Widget>&)> derefUPLess =
    [](const std::unique_ptr<Widget>& p1,
            const std::unique_ptr<Widget>& p2) {return *p1 < *p2;};

但是,不仅写起来啰嗦,而且因为std::functionauto的行为并不相同。auto持有的类型与lambda表达是相同,而std::function对于任意的函数签名均持有一个固定大小的对象。如果这个大小与闭包大小不同,则会申请新的空间。这会浪费内存。而且犹豫标准对于闭包实现的限制,通常来讲auto对象的运行速度更快。

避免无谓的错用类型

std::vector<int> v;
unsigned sz1 = v.size();    //实际的类型应是 std::vector<int>::size_type
auto sz2 = v.size();

std::unordered_map<std::string, int> m;
for (const std::pair<std::string, int>& p : m) {
    ...
}
for (const auto & p : m) {  // 实际的类型应是 const std::pair<const std::string, int>&
    ...
}

对于第一种情况,在不同的平台,比如32位和64位平台,可能会有不同的表现,导致难以发现的错误。
对于第二中情况,由于类型的不匹配,导致生成无谓的临时对象,不仅会增加开销,而且对p取地址还会有不同的行为发生。

推荐使用auto的原因

  • 使用的类型更精确
  • 使程序更具效率
  • 当更改一处类型时,比如函数返回值,不需要去修改其他地方

auto的缺点

auto从初始化表达式推断类型,但是,初始化表达式的类型有时候并不是我们期待的。这所产生的问题在第二章和第六章阐述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值