当前位置: 首页 > news >正文

wordpress好看的中文主题seo外包网络公司

wordpress好看的中文主题,seo外包网络公司,网站开发流程图 最,重庆做网站人才1. 基于范围的for循环语法 C11标准引入了基于范围的for循环特性,该特性隐藏了迭代器 的初始化和更新过程,让程序员只需要关心遍历对象本身,其语法也 比传统for循环简洁很多: for ( range_declaration : range_expression ) {loo…

1. 基于范围的for循环语法

C++11标准引入了基于范围的for循环特性,该特性隐藏了迭代器
的初始化和更新过程,让程序员只需要关心遍历对象本身,其语法也
比传统for循环简洁很多:

for ( range_declaration : range_expression )
{loop_statement;
}

基于范围的for循环不需要初始化语句、条件表达式以及更新表
达式,取而代之的是一个范围声明和一个范围表达式。其中范围声明
是一个变量的声明,其类型是范围表达式中元素的类型或者元素类型
的引用。而范围表达式可以是数组或对象,对象必须满足以下2个条件
中的任意一个。
    1.对象类型定义了begin和end成员函数。

    2. 定义了以对象参数为类型的begin和end普通函数。

#include <iostream>
#include <string>
#include <map>
std::map<int, std::string> index_map{ {1, "hello"}, {2, "world"},
{3, "!"} };
int int_array[] = { 0, 1, 2, 3, 4, 5 };
int main()
{for (const auto &e : index_map){std::cout << "key=" << e.first << ", value=" << e.second <<std::endl;}for (auto e : int_array){std::cout << e << std::endl;}
}

如果不会在循环过程中修改引用对象,那么推荐在范围声明中加上const限定符以帮助编译器生成更加高效的代码:
 

#include <iostream>
#include <vector>struct X
{X() { std::cout << "default ctor" << std::endl; }X(const X& other){std::cout << "copy ctor" << std::endl;}
};int main()
{std::vector<X> x(10);std::cout << "for (auto n : x)" << std::endl;for (auto n : x){}std::cout << "for (const auto &n : x)" << std::endl;for (const auto &n : x){}
}

2. 实现自己的range-for

//since C++17, until C++20for (range-declaration : range-expression )
{loop-statement
}The above syntax produces code equivalent to the following except for the lifetime expansion of temporaries of range-expression.
{auto && __range = range-expression ;  //gcc//auto &_range = range-expression;   //clangauto __begin = begin-expr ;auto __end = end-expr ;for ( ; __begin != __end; ++__begin){range-declaration = *__begin;loop-statement}
}

其中operator *用于编译器生成解引用代码,operator !=用于生成循环条件代码,而前缀版本的operator ++用于更新迭代器。

#include <iostream>template<typename T, size_t L>
class Iter
{
public:Iter(T* data, size_t idx):data{data}, idx{idx}{}T& operator*(){return *(data + idx);}Iter& operator++()//前缀operator ++{idx++;return *this;}bool operator != (const Iter& other){return other.idx != this->idx;}private:size_t idx{0};T* data;
};template<typename T, size_t L>
class array
{
public:using iterator = Iter<T, L>;array(std::initializer_list<T> list){T * ptr = data;for (const auto e : list){*ptr = e;ptr++;}}iterator begin(){return iterator(data, 0);}iterator end(){return iterator(data, L);}
private:T data[L]{};
};int main(void)
{array<int, 4> arr{10,20,30,40};for(auto iter = arr.begin(); iter != arr.end(); ++iter){std::cout << *iter << ' ';}for (const auto i : arr){std::cout << i << ' ';}std::cout << std::endl;
}

以上代码,类模板array中实现了iterator begin()和 iterator end(),在迭代器类Iter中实现了operator*(), operator++()[注意这里是前缀operator++],以及operator!=。

3. 临时范围表达式的陷阱

无论是C++11还是C++17,基于范围的for循环伪代码

//since C++17, until C++20

for (range-declaration : range-expression )

{

    loop-statement

}

The above syntax produces code equivalent to the following except for the lifetime expansion of temporaries of range-expression.

{

    auto && __range = range-expression ;  //gcc版本

    //auto &_range = range-expression;   //clang版本

    auto __begin = begin-expr ;

    auto __end = end-expr ;

    for ( ; __begin != __end; ++__begin)

    {

          range-declaration = *__begin;

          loop-statement

    }

}

对于下面这个例子代码

#include <iostream>
#include <vector>class RangeFor
{
public:std::vector<int>& items() { return data; }
private:std::vector<int> data{10, 20, 30, 40};
};RangeFor foo()
{RangeFor data;return data;
}int main(void)
{/*step 1: foo() return rvalue;step 2: items() return l_val_ref of rvalue.step 3: __range is an align for l_val_ref.step 4: rvalue(temp value) destory.now __range reference to dangling refenence.*/for (const auto& x : foo().items()) //gcc: unexcepted number//clang: segmentation fault{std::cout << x << " ";}return 0;
}

我们从C++ Insights分析看:

#include <iostream>
#include <vector>class RangeFor
{public: inline std::vector<int, std::allocator<int> > & items(){return this->data;}private: std::vector<int, std::allocator<int> > data;public: // inline RangeFor(RangeFor &&) noexcept = default;// inline ~RangeFor() noexcept = default;// inline constexpr RangeFor() noexcept(false) = default;
};RangeFor foo()
{RangeFor data = RangeFor() /* NRVO variable */;return data;
}int main()
{{std::vector<int, std::allocator<int> > & __range1 = foo().items();__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > __begin1 = __range1.begin();__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > __end1 = __range1.end();for(; __gnu_cxx::operator!=(__begin1, __end1); __begin1.operator++()) {int const & x = __begin1.operator*();std::operator<<(std::cout.operator<<(x), " ");}}return 0;
}

从clang角度编译器看: std::vector<int, std::allocator<int> > & __range1 = foo().items();

foo()返回临时右值,这个临时右值调用items返回了一个左值引用,然后 __range有引用了这个临时右值接口items返回的左值引用;这个句子结束后,这个临时右值销毁了,这个时候__range其实引用的是一个已经不存在对象的数据。

auto && __range = range-expression ;  

这个是是cpp reference上说的(应该是gcc版本的)。其最终结果也是一样的;我们来分析下上面那段代码:

/*
    step 1: foo() return temp rvalue;
    step 2: items() return l_val_ref of rvalue.
    step 3: __range is an alias for l_val_ref.
    step 4: rvalue(temp value) destory.
    now __range reference to dangling refenence.
*/
    for (const auto& x : foo().items()) //gcc: unexcepted number
                                                         //clang: segmentation fault
    {
        std::cout << x << " ";
    }

可能这里有些人觉得 定义了const auto&x可以捕获临时变量,这个是没错的;对于这个range-for来回代码相当于如下:

#include <iostream>
#include <vector>#include <string>class RangeFor
{
public:RangeFor() : data("rangeFor") { std::cout << "ctor" << std::endl; }std::string& getItems(){std::cout << "get data" << std::endl;return data;}~RangeFor(){std::cout << "dtor" << std::endl;data = "";}private:std::string data;
};RangeFor foo()
{RangeFor data;return data;
}int main(void)
{/*step 1: foo() return rvalue;step 2: items() return l_val_ref of rvalue.step 3: vec is an align for l_val_ref.step 4: rvalue(temp value) destory.*/const auto& ret = foo().getItems();//note: now vec reference to dangling refenence.if (ret.empty()){std::cout << "empty string" << std::endl;}else{std::cout << ret << std::endl;}return 0;
}

const auto& ret = foo(), getItems();这个 const左值引用ret作用于getItems返回的左值引用,这个getItems返回的左值引用(打比喻是毛)的真真数据是foo()返回的临时变量(打比喻是皮),这行代码结束后,临时变量被销毁了。getItems返回的左值引用,用一句话总结就是:皮之不存毛将焉附!

4. 基于范围的for 循环的初始化

C++17 引入了if 和switch 控制结构的可选初始化,C++20 现在为基于范围的for 循环引入了这
样一个可选的初始化。

for ( init-statement(optional); range-declaration : range-expression )

{

      loop-statement

}

The above syntax produces code equivalent to the following:

{

       init-statement

      auto && __range = range-expression ;

      auto __begin = begin-expr ;

      auto __end = end-expr ;

      for ( ; __begin != __end; ++__begin)

      {

            range-declaration = *__begin;

            loop-statement

       }

}

我们来看个代码示例:

#include <iostream>
#include <vector>class RangeFor
{
public:std::vector<int>& items() { return data; }
private:std::vector<int> data{10, 20, 30, 40};
};RangeFor foo()
{RangeFor data;return data;
}int main(void)
{//const auto& thing = foo();//for (const auto& x : thing.items())// C++17for (auto thing = foo(); const auto& x :thing.items()) //since c++20{std::cout << x << " ";}return 0;
}

http://www.hkea.cn/news/603426/

相关文章:

  • 培训教育的网站怎么做东莞做网站的联系电话
  • 云南做网站的公司外贸谷歌优化
  • 网页设计学徒培训可试学巢湖seo推广
  • 让顾客心动的句子seo模拟点击软件源码
  • 设计类专业包括哪些kj6699的seo综合查询
  • 手机网站制作哪家好查关键词
  • 米拓企业网站管理系统电商培训机构排名前十
  • 做效果图有哪些网站seo点击排名
  • 网络营销推广网站收录seo推广排名平台有哪些
  • 产品经理如何看待网站开发广州软件系统开发seo推广
  • wordpress 忘记管理员如何做网站seo
  • app和网站哪个有优势淘宝关键词排名
  • wordpress该域名宁波网站seo公司
  • 建购物网站怎么建呀简单的网站建设
  • 江苏省建设教育协会网站首页百度知道合伙人答题兼职入口
  • 做优化的网站平台搭建
  • 做网站需要多久网络推广是什么专业
  • 厦门加盟网站建设线上推广营销
  • 定制网站案例seo搜索引擎优化薪酬
  • 网站制作成功后怎么使用浏览器观看b站视频的最佳设置
  • 一家专门做开网店的网站北京seo专员
  • 专业企业网站搭建服务头条权重查询
  • 去哪儿网站上做民宿需要材料免费的黄冈网站有哪些平台
  • 网站建设网现在推广什么app最挣钱
  • 嘉兴装修公司做网站安装百度到桌面
  • 电商网站特点外贸营销网站建站
  • 上海市住房城乡建设管理委员会网站网络营销软文范例大全800
  • 莱芜区政协网站做网络优化的公司排名
  • 太原网站建设开发公司电商运营基本知识
  • php做企业网站seo网站推广企业