If you can't read please download the document
Upload
mikhail-matrosov
View
548
Download
1
Embed Size (px)
Citation preview
2011
++: [email protected]@aligntech.com
1
ToDo: add links1
" ++: ", , C++ Russia 20172
++ 12 , 3D . Align Technology. , . , ++. 3D CAD . , .2
goo.gl/TL15Rg" ++: ", , C++ Russia 20173
3
++17
++11/14
++98High levelExpert level
Modern C++Almost the same :(
Within C++ is a smaller, simpler, safer language struggling to get outBjarne Stroustrup
" ++: ", , C++ Russia 20174
4
High level: RAII (exceptions) - STL boost
" ++: ", , C++ Russia 20175Expert level: new/delete, , , , ,
, boost: http://stackoverflow.com/q/8851670/261217
5
6Which boost features overlap with C++11?
1. , ++11 boost?6
conststd::vectorextract(conststd::vector&points){std::vectorresult;result.clear(); if(points.size()==0)returnresult; intp=0;boolfound=false;for(inti=1;i=0){result.clear();Pointnan;nan.x=sqrt(-1);nan.y=sqrt(-1);result.push_back(nan);returnresult;}if(++i>=points.size())i=0;} returnstd::move(result);}7
.7
" ++: ", , C++ Russia 20178conststd::vectorextract(conststd::vector&points){std::vectorresult;result.clear(); if(points.size()==0)returnresult; intp=0;boolfound=false;for(inti=1;i=0){result.clear();Pointnan;nan.x=sqrt(-1);nan.y=sqrt(-1);result.push_back(nan);returnresult;}if(++i>=points.size())i=0;} returnstd::move(result);}std::vectorextractRight(std::vectorpoints){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); if(middle!=points.end())rotate(points,std::next(middle)); if(!is_partitioned(points,isRight))throwstd::runtime_error("Unexpectedorder"); points.erase(partition_point(points,isRight),points.end()); returnpoints;}
8
" ++: ", , C++ Russia 20179conststd::vectorextract(conststd::vector&points){
1. No reason to return container by const value9
" ++: ", , C++ Russia 201710std::vectorextract(conststd::vector&points){
" ++: ", , C++ Russia 201711std::vectorextract(conststd::vector&points){std::vectorresult;result.clear();
1. No reason to clear container after it is default constructed11
" ++: ", , C++ Russia 201712std::vectorextract(conststd::vector&points){std::vectorresult;
" ++: ", , C++ Russia 201713std::vectorextract(const std::vector&points){std::vectorresult; if(points.size()==0)returnresult;
1. Use empty()13
" ++: ", , C++ Russia 201714std::vectorextract(const std::vector&points){std::vectorresult; if(points.empty())returnresult;
" ++: ", , C++ Russia 201715std::vectorextract(conststd::vector&points){std::vectorresult; if(points.empty())returnresult; intp=0;boolfound=false;for(inti=1;i=points.size())i=0;}
!
Similar code snippets most probably serve similar purpose, and thus needs to be represented by a single entity.28
" ++: ", , C++ Russia 201729autoappendResult=[&](intfrom,intto,boolshouldBeRight){inti=from;while(i!=to){if(isRight(points[i])!=shouldBeRight){result={Point(NAN,NAN)};returnfalse;}if(shouldBeRight)result.push_back(points[i]);if(++i>=points.size())i=0;}returntrue;}; boolsuccess=appendResult(p,q,true)&&appendResult(q,p,false);
29
" ++: ", , C++ Russia 201730autoappendResult=[&](intfrom,intto,boolshouldBeRight){inti=from;while(i!=to){if(isRight(points[i])!=shouldBeRight)throwstd::runtime_error("Unexpectedorder");if(shouldBeRight)result.push_back(points[i]);if(++i>=points.size())i=0;}}; appendResult(p,q,true);appendResult(q,p,false);
What other alternatives do we have to represent an error?30
" ++: ", , C++ Russia 201731appendResult(p,q,true);appendResult(q,p,false); returnstd::move(result);}
RVO is disabled because standard says that type of returned value and return type of function should be the same.31
" ++: ", , C++ Russia 201732appendResult(p,q,true);appendResult(q,p,false); returnresult;}
32
" ++: ", , C++ Russia 201733std::vectorextract(conststd::vector&points){std::vectorresult; if(points.empty())returnresult; autoisRight=[](constPoint&pt){returnpt.x>=0;}; autofindBoundary=[&](boolrightToLeft){for(inti=1;i=points.size())i=0;}}; appendResult(p,q,true);appendResult(q,p,false); returnresult;}conststd::vectorextract(conststd::vector&points){std::vectorresult;result.clear(); if(points.size()==0)returnresult; intp=0;boolfound=false;for(inti=1;i=0){result.clear();Pointnan;nan.x=sqrt(-1);nan.y=sqrt(-1);result.push_back(nan);returnresult;}if(++i>=points.size())i=0;} returnstd::move(result);}intp=findBoundary(false);intq=findBoundary(true);appendResult(p,q,true);appendResult(q,p,false);
33
" ++: ", , C++ Russia 201734012345612340123456
qppq012345645601pq
" ++: ", , C++ Russia 2017350123456 p
Algorithm to find first element - adjacent_find().adjacent_find() returns iterator to the first element in the pair, how to retrieve the second? How is std::next() better than it+1? How is different from ++it?35
" ++: ", , C++ Russia 2017366012345
1. Algorithm to move it to beginning rotate()36
" ++: ", , C++ Russia 2017375601234
" ++: ", , C++ Russia 2017385601234
Algorithm to check structure is_partitioned()Algorithm to detect the tail partition_point()38
std::vectorextractRight(std::vectorpoints){" ++: ", , C++ Russia 201739
1. In which scenario this signature is preferable?39
std::vectorextractRight(std::vectorpoints){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; " ++: ", , C++ Russia 201740
std::vectorextractRight(std::vectorpoints){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); " ++: ", , C++ Russia 201741
Why do we need & in []?What exactly this lambda function correspond to?41
std::vectorextractRight(std::vectorpoints){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); if(middle!=points.end())rotate(points,std::next(middle)); " ++: ", , C++ Russia 201742
std::vectorextractRight(std::vectorpoints){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); if(middle!=points.end())rotate(points,std::next(middle)); if(!is_partitioned(points,isRight))throwstd::runtime_error("Unexpectedorder"); " ++: ", , C++ Russia 201743
std::vectorextractRight(std::vectorpoints){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); if(middle!=points.end())rotate(points,std::next(middle)); if(!is_partitioned(points,isRight))throwstd::runtime_error("Unexpectedorder"); points.erase(partition_point(points,isRight),points.end()); " ++: ", , C++ Russia 201744
std::vectorextractRight(std::vectorpoints){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); if(middle!=points.end())rotate(points,std::next(middle)); if(!is_partitioned(points,isRight))throwstd::runtime_error("Unexpectedorder"); points.erase(partition_point(points,isRight),points.end()); returnpoints;}" ++: ", , C++ Russia 201745
" ++: ", , C++ Russia 201746conststd::vectorextract(conststd::vector&points){std::vectorresult;result.clear(); if(points.size()==0)returnresult; intp=0;boolfound=false;for(inti=1;i=0){result.clear();Pointnan;nan.x=sqrt(-1);nan.y=sqrt(-1);result.push_back(nan);returnresult;}if(++i>=points.size())i=0;} returnstd::move(result);}std::vectorextractRight(std::vectorpoints){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); if(middle!=points.end())rotate(points,std::next(middle)); if(!is_partitioned(points,isRight))throwstd::runtime_error("Unexpectedorder"); points.erase(partition_point(points,isRight),points.end()); returnpoints;}std::vectorextract(conststd::vector&points){std::vectorresult; if(points.empty())returnresult; autoisRight=[](constPoint&pt){returnpt.x>=0;}; autofindBoundary=[&](boolrightToLeft){for(inti=1;i=points.size())i=0;}}; appendResult(p,q,true);appendResult(q,p,false); returnresult;}
46
" ++: ", , C++ Russia 2017470123middlefirstlast
456
47
" ++: ", , C++ Russia 201748Sean Parent: C++ Seasoning (no raw loops)
" ++: ", , C++ Russia 201749
" ++: ", , C++ Russia 201750
012345601234
" ++: ", , C++ Russia 2017510123456! rotate()!
? ?51
52templateclassWrappingIterator:publicboost::iterator_adaptor{usingBase=boost::iterator_adaptor; public:WrappingIterator()=default;WrappingIterator(Itit,Itbegin,Itend):Base(it),m_end(end),m_size(end-begin){} private:friendclassboost::iterator_core_access; typenameBase::referencedereference()const{autoit=this->base_reference();return*(it?Can we use return type deduction here?Why it is UB?52
53templateclassWrappingIterator:publicboost::iterator_facade{public:WrappingIterator()=default;WrappingIterator(Itit,Itbegin,Itend):m_begin(begin),m_size(end-begin),m_offset(it-begin){}templateWrappingIterator(constWrappingIterator&other):m_begin(other.m_begin),m_size(other.m_size),m_offset(other.m_offset){} private:friendclassboost::iterator_core_access;templatefriendclassWrappingIterator;usingBase=boost::iterator_facade;
//Coreinterfacefunctions (on the next slide)
Itm_begin;size_tm_size;size_tm_offset;};
Why we need template constructor?53
54typenameBase::referencedereference()const{return*(m_begin+(m_offset=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);});
57
" ++: ", , C++ Russia 201758autoextractRight(conststd::vector&points){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); middle=middle!=points.end()?std::next(middle):points.begin(); autobegin=makeWrappingIterator(middle,points.begin(),points.end());autorotated=boost::make_iterator_range(begin,begin+points.size());
ToDo: rotated = boost::make_iterator_range(begin, end);58
" ++: ", , C++ Russia 201759autoextractRight(conststd::vector&points){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); middle=middle!=points.end()?std::next(middle):points.begin(); autobegin=makeWrappingIterator(middle,points.begin(),points.end());autorotated=boost::make_iterator_range(begin,begin+points.size()); if(!is_partitioned(rotated,isRight))throwstd::runtime_error("Unexpectedorder");
Why it is not necessary to specify std:: before is_partitioned()?59
" ++: ", , C++ Russia 201760autoextractRight(conststd::vector&points){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); middle=middle!=points.end()?std::next(middle):points.begin(); autobegin=makeWrappingIterator(middle,points.begin(),points.end());autorotated=boost::make_iterator_range(begin,begin+points.size()); if(!is_partitioned(rotated,isRight))throwstd::runtime_error("Unexpectedorder"); autoend=partition_point(rotated,isRight);
60
" ++: ", , C++ Russia 201761autoextractRight(conststd::vector&points){usingnamespaceboost::range;usingnamespaceboost::algorithm; autoisRight=[](constPoint&pt){returnpt.x>=0;}; automiddle=adjacent_find(points,[&](auto&&pt1,auto&&pt2){return!isRight(pt1)&&isRight(pt2);}); middle=middle!=points.end()?std::next(middle):points.begin(); autobegin=makeWrappingIterator(middle,points.begin(),points.end());autorotated=boost::make_iterator_range(begin,begin+points.size()); if(!is_partitioned(rotated,isRight))throwstd::runtime_error("Unexpectedorder"); autoend=partition_point(rotated,isRight); returnboost::make_iterator_range(begin,end);}
What is the next logical step to generalization?Which of these algorithms (including rotate()) benefit from random access iterator?61
" ++: ", , C++ Russia 2017620123456!
62
" ++: ", , C++ Russia 201763templateautoextractIf(Itfirst,Itlast,Predicatep){
63
" ++: ", , C++ Russia 201764templateautoextractIf(It first,Itlast,Predicatep){usingnamespaceboost::range;usingnamespaceboost::algorithm; automiddle=adjacent_find(first,last,[&](auto&&a,auto&&b){return!p(a)&&p(b);}); middle=middle!=last?std::next(middle):first;
64
" ++: ", , C++ Russia 201765templateautoextractIf(Itfirst,Itlast,Predicatep){usingnamespaceboost::range;usingnamespaceboost::algorithm; automiddle=adjacent_find(first,last,[&](auto&&a,auto&&b){return!p(a)&&p(b);}); middle=middle!=last?std::next(middle):first; autorotated=boost::join(boost::make_iterator_range(middle,last), boost::make_iterator_range(first,middle));
65
" ++: ", , C++ Russia 201766templateautoextractIf(Itfirst,Itlast,Predicatep){usingnamespaceboost::range;usingnamespaceboost::algorithm; automiddle=adjacent_find(first,last,[&](auto&&a,auto&&b){return!p(a)&&p(b);}); middle=middle!=last?std::next(middle):first; autorotated=boost::join(boost::make_iterator_range(middle,last), boost::make_iterator_range(first,middle)); if(!is_partitioned(rotated,p))throwstd::runtime_error("Unexpectedorder");
66
" ++: ", , C++ Russia 201767templateautoextractIf(Itfirst,Itlast,Predicatep){usingnamespaceboost::range;usingnamespaceboost::algorithm; automiddle=adjacent_find(first,last,[&](auto&&a,auto&&b){return!p(a)&&p(b);}); middle=middle!=last?std::next(middle):first; autorotated=boost::join(boost::make_iterator_range(middle,last), boost::make_iterator_range(first,middle)); if(!is_partitioned(rotated,p))throwstd::runtime_error("Unexpectedorder"); autoend=partition_point(rotated,p);
67
" ++: ", , C++ Russia 201768templateautoextractIf(Itfirst,Itlast,Predicatep){usingnamespaceboost::range;usingnamespaceboost::algorithm; automiddle=adjacent_find(first,last,[&](auto&&a,auto&&b){return!p(a)&&p(b);}); middle=middle!=last?std::next(middle):first; autorotated=boost::join(boost::make_iterator_range(middle,last), boost::make_iterator_range(first,middle)); if(!is_partitioned(rotated,p))throwstd::runtime_error("Unexpectedorder"); autoend=partition_point(rotated,p); returnboost::make_iterator_range(rotated.begin(),end);}
68
PROFIT!" ++: ", , C++ Russia 201769
69
Performance?RangeTraverse timestd::vector1.0Joined range of two iterator ranges
" ++: ", , C++ Russia 201770
100M elementsdoublesum=0;for(constPoint&v:range)sum+=v.x;
70
Performance?RangeTraverse timestd::vector1.0Joined range of two iterator ranges1.18
" ++: ", , C++ Russia 201771
100M elementsdoublesum=0;for(constPoint&v:range)sum+=v.x;
Additional questions for winners: rotate()? ? - N ?71
" ++: ", , C++ Russia 201772 //lambdafunctions(includinggeneric)//ternaryoperator//exceptions//transientparametersstd::vector::empty()adjacent_find()rotate()is_partitioned()partition_point()std::next();//custommake-function//templateparametersforiterators//templateparametersforpredicates//functionreturntypedeductionboost::rangeboost::algorithmboost::iterator_adaptorboost::make_iterator_range()boost::join() !
72