📚
cpp
  • README.md
  • Effective c++
    • 1.让自己习惯c++
    • 2.构造/析构/赋值运算
    • 3.资源管理
    • 4.设计与声明
    • 5.实现
    • 6.继承与面向对象设计
    • 7.模板与泛型编程
    • 8.定制new和delete
  • More effective c++
    • 1.基础议题
    • 2.操作符
    • 3.异常
    • 4.效率
    • 5.技术
    • 6.杂项讨论
  • effective modern c++
    • 1.型别推导
    • 2.auto
    • 3.转向现代c++
    • 4.智能指针
    • 5.右值引用,移动语义和完美转发
    • 6.lambda表达式
    • 7.并发API
    • 8.微调
  • stl源码剖析
  • cpp-concurrency-in-action
Powered by GitBook
On this page
  • 条款05:优先选用auto,而非显示型别声明
  • 当使用auto推导的型别不符合要求的时候,使用带显式型别的初始化物习惯用法

Was this helpful?

  1. effective modern c++

2.auto

上一个条款也有谈到auto,auto看起来很简单,但是还是有些情况需要注意。这里主要讲如何去引导auto得出正确的结果

条款05:优先选用auto,而非显示型别声明

这个条款给出几个理由,让我们优先选择使用auto。下面几个例子可以展示

int x;      //忘记初始化

template<typename It>
void dwim(It a,It b){
    while(a!=b){
        typename std::iterator_traits<It>::value_type
            currValue = *b;         //定义又臭又长
    }
}

auto x=5;   //必须初始化

template<typename It>
void dwim(It a,It b){
    while(a!=b){
        auto currValue = *b;         //只需要auto即可
    }
}

//一般是有lambda的时候都是用auto,不然你拿捏不了型别

auto func=[](int a,int b){return a==b;};
auto func_auto=[](auto a,auto b){return a==b;};

//不用auto也是可以声明lambda表达式的,可以用std::function,但是会啰嗦,以及占用更多的内存。

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 *pa<*p2;};
//可以看到,上面的声明巨麻烦,并且std::function会占用更多的内存

上面主要讲的是auto的便利,下面一个例子能体现使用auto的更大的好处。

std::unordered_map<std::string,int> ma;

for(const std::pair<std::string,int>&p:ma){
    //do something
}

可以看到,大家应该都觉得这里没啥问题。但是map的key是默认const的。也就是这里真实的构造其实是 const std::pait,这里不匹配,要执行编译器强制转换。将所有的key复制一遍。开销巨大。可能有时候你写出这种代码,自己都不知道哪里出了问题。使用auto的话,这里什么问题都不会存在了。

当使用auto推导的型别不符合要求的时候,使用带显式型别的初始化物习惯用法

可以看到,类型是std::_Bit_reference&,这个类型我相信大家应该都没用过。

这个条款说的就是,有的时候还是使用显式声明比较好。但这不是说不用auto,还是建议使用auto,因为这种情况不多。

Previous1.型别推导Next3.转向现代c++

Last updated 5 years ago

Was this helpful?

有些方法返回的不是你所想的结果。因为有些类被设计为代理类,返回值可以隐式转换到你认为的结果。但是使用auto却不可以,auto会为你推导出本来的结果。vector< bool >中operator[]就是一个典型的例子,他返回值不是bool&,如果用auto接收,就会出乎你的意料。使用上一节末尾的编译器识别类型,得出vector< bool >中operator[]返回的结果类型为