C++自动推断和循环

C++自动推断和循环

目录

一.自动推断说明

1. 说明

自动推断有2个常用关键字auto与 decltype.具体如下表所示:

  • auto: 自动推断的关键字,一切赋值时需要的情况(for循环)(偷懒利器)
    • auto只能对有初值的类型进行推断,默认以赋值的方式进行获取(引用需要显示说明),如果复制的类型为const可以自动添加该限定否则需要手动设置.
  • decltype: 获取类型字段,多用于模板或者已经有同类型的变量
    • 获取表达式的类型,不会计算表达结果.(更多用于模板)

2.例程

class CGlobalSection
{
    ...
    const std::vector< CCandidateDoor >& getConfirmedDoor() const
    {
        return m_confirmed_doors;
    }

    std::vector< CCandidateDoor >& getConfirmedDoor()
    {
        return m_confirmed_doors;
    }

    std::vector< CCandidateDoor > m_confirmed_doors;
};

void func1()
{
    CGlobalSection global_section;

    std::vector<CCandidateDoor > confirmed_doors = global_section.getConfirmedDoor(); //原来很长

    auto        confirmed_doors1  = global_section.getConfirmedDoor();  //相当于 std::vector<CCandidateDoor>
    auto       &confirmed_doors2  = global_section.getConfirmedDoor(); //相当于 std::vector<CCandidateDoor> &
    auto const &confirmed_doors3  = global_section.getConfirmedDoor(); //相当于 std::vector<CCandidateDoor> const &

   decltype(confirmed_doors3)  confirmed_doors4; //confirmed_doors4的类型为 std::vector<CCandidateDoor> const &
}

二. 循环说明

1.说明

c++11以后的循环优化是为了解决以前循环冗余难写的痛点而增加的.(向其它高级语言靠齐) 本质上调用的是迭代器,通过初始化列表的统一处理(迭代器化),也能遍历普通的数组.因此使用循环优化的代码效率已到极致.

2.例程

例程1.

//修改前
void CPartitionNavigation::dealWithDoorMap( const algo::CGlobalSection&      global_section,
                                            mrpt::slam::COccupancyGridMap2D& merge_map)
{
   std::vector< algo::CCandidateDoor > confirmed_doors = global_section.getConfirmedDoor();
    double                              threshold       = 0.3;

    for ( size_t i = 0; i < confirmed_doors.size(); i++)
    {
        algo::CRobotPose2D middle_pose = confirmed_doors.at( i).getMiddlePose();  //能用 []方法访问就不要用 at()方法访问.除非你不在范围且自己处理异常!!.

        fillMapBlank( merge_map, threshold, middle_pose);
    }
}
//修改后
void CPartitionNavigation::dealWithDoorMap( const algo::CGlobalSection&      global_section,
                                            mrpt::slam::COccupancyGridMap2D& merge_map)
{
    const double threshold = 0.3;
    auto &confirmed_doors = global_section.getConfirmedDoor(); //按引用.不引起复制

    for(auto &v : confirmed_doors) //自动推断类型并以引用方式获取.(std::vector< algo::CCandidateDoor > const)(此时不能调用v的非const函数)
    {                              //如果需要按值获取(可以调用任何成员函数) 改为 for(auto v : confirmed_doors)
        fillMapBlank( merge_map, threshold, v.getMiddlePose());
    }
}

例程2

//修改前
void func()
{
    std::list<CChainCell>  chain_list = section_chain.getChainList(); //复制一次浪费
    std::list<CChainCell>::iterator it; //变量不一样需要重新写

    for (it = chain_list.begin(); it != chain_list.end(); it++) //it++低效
    {
        small_section_map.setCell(it->getIdx(), it->getIdy(), 1);
    }
}

//优化版本1
void func()
{
    auto &chain_list = section_chain.getChainList();        //引用获取高效
    for (auto it = chain_list.begin(); it != chain_list.end(); ++it) //it自动推断, ++it高效
    {
        small_section_map.setCell(it->getIdx(), it->getIdy(), 1); //不修改it的值
    }
}

//优化版本2 (推崇)
void func()
{
    for(auto &v : section_chain.getChainList()) //没有复制.简单高效
    {
        small_section_map.setCell(v.getIdx(), v.getIdy(), 1); 
    }
}