C++0x增加了诸多的feature,使C++俨然变成了新的语言,遂拙记一些。
Moving semantics
C++ has supported copying object,but it is less efficient when a large object is copying. So C++0x adds supportfor move object state:
Widget w1;
Widget w2(w1); //copy w1 to w2
Widget w3;
Widget w4(std::move(w3)); //move w3 to w4, and w3 w4 point to the same object.
Typedef vector<T> Vec;
Vec createVec();
Vec tv = createVec(); //implicit move request in C++0x
Rvalue Reference
Syntax: T&&
As always:
Lvaluesmay bind to lvalue references
Rvaluesmay bind to lvalue references to const
In addition:
Rvaluesmay bind to rvalue references to non-const
Lvaluesmay not bind to rvalue references
class Widget {
public:
Widget(const Widget&); // copy constructor
Widget(Widget&&); // move constuctor
Widget& operator=(const Widget&); // copy assignment op
Widget& operator=(Widget&&); // move assignment op
…
};
Widget createWidget(); // factory function
Widget w1;
Widget w2 = w1; // lvalue src ⇒ copy req’d
w2 = createWidget(); // rvalue src ⇒ move okay
w1 = w2; // lvalue src ⇒ copy req’d
class Widget {
public:
Widget(Widget&& rhs): pds(rhs.pds) // take source’s value
{ rhs.pds = nullptr; } // leave source in valid state
Widget& operator=(Widget&& rhs)
{
if (this == &rhs) return *this;
delete pds; // get rid of current value
pds = rhs.pds; // take source’s value
rhs.pds = nullptr; // leave source in valid state
return *this;
}
…
private:
struct DataStructure;
DataStructure *pds;
}
Explicit Move Request
class WidgetBase { … };
class Widget: public WidgetBase {
public:
Widget(Widget&& rhs) // move constructor
: WidgetBase(std::move(rhs)), // request move
s(std::move(rhs.s)) // request move
{ … }
Widget& operator=(Widget&& rhs) // move assignment
{
WidgetBase::operator=(std::move(rhs)); // request move
s = std::move(rhs.s); // request move
return *this;
}
…
};
New Container
· Unordered_map
map -> log(n) insertion, retrieval, iteration is efficient (and ordered by keycomparison).
unordered_map-> constant time insertion and retrieval, iteration time is not guarantee tobe efficient.
· array
· forward_list
· unordered_set
· unordered_multiset
· unordered_multimap
Lambda Expression
It is also called anonymousfunction, and a function defined, and possibly called without being bound to anidentifier.
[capture](parameters)->return-type{body}
[](int x, int y) { return x + y; } // implicit return type from 'return' statement
[](int& x) { ++x; } // no return statement -> lambda functions' return type is 'void'
[]() { ++global_x; } // no parameters, just accessing a global variable
[]{ ++global_x; } // the same, so () can be omitted
A lambda function can refer to identifiers declared outside thelambda function. The set of these variables is commonly called a closure. Closures are defined between square brackets [ and ] in the declaration of lambda expression. The mechanismallows these variables to be captured by value or by reference. The followingtable demonstrates this:
[] //no variables defined. Attempting to use any external variables in the lambda is an error.
[x, &y] //x is captured by value, y is captured by reference
[&] //any external variable is implicitly captured by reference if used
[=] //any external variable is implicitly captured by value if used
[&, x] //x is explicitly captured by value. Other variables will be captured by reference
[=, &z] //z is explicitly captured by reference. Other variables will be captured by value
Lambda functions are function objects of animplementation-dependent type; this type's name is only available to thecompiler. If the user wishes to take a lambda function as a parameter, the typemust be a template type, or they must create a std::function or a similar object to capture the lambda value. The use ofthe auto keyword can help store the lambdafunction,
auto my_lambda_func = [&](int x) { /*...*/ };
auto my_onheap_lambda_func = new auto([=](int x) { /*...*/ });
#include<functional>
#include<vector>
#include<iostream>
double eval(std::function<double(double)> f, double x = 2.0){return f(x);}
int main(){
std::function<double(double)> f0 = [](double x){return 1;};
auto f1 = [](double x){return x;};
decltype(f0) fa[3] = {f0,f1,[](double x){return x*x;}};
std::vector<decltype(f0)> fv = {f0,f1};
fv.push_back ([](double x){return x*x;});
for(int i=0;i<fv.size();i++) std::cout << fv[i](2.0) << "\n";
for(int i=0;i<3;i++) std::cout << fa[i](2.0) << "\n";
for(auto &f : fv) std::cout << f(2.0) << "\n";
for(auto &f : fa) std::cout << f(2.0) << "\n";
Improving Performance of std::function
http://www.drdobbs.com/cpp/efficient-use-of-lambda-expressions-and/232500059?pgno=2
std::count_if(v.begin(), v.end(),std::cref([n](int i){return i%n == 0;}));
async
The templatefunction async runs the function f asynchronously (potentially in aseparate thread) and returns a std::future that will eventually hold theresult of that function call.
template <typename RAIter>
int parallel_sum(RAIter beg, RAIter end){
typename RAIter::difference_type len = end-beg;
if(len < 1000)
return std::accumulate(beg, end, 0);
RAIter mid = beg + len/2;
auto handle = std::async(std::launch::async, parallel_sum<RAIter>, mid, end);
int sum = parallel_sum(beg, mid);
return sum + handle.get();
}
§ If the async flag isset (i.e. policy & std::launch::async != 0), then async spawns a new thread of executionas if by std::thread(f, args...), except that if the function f returns a value or throws anexception, it is stored in the shared state accessible through the std::future that async returns to the caller.
§ If the deferred flagis set (i.e. policy & std::launch::deferred != 0), then async converts args... the same way as by std::thread constructor, but does not spawn anew thread of execution. Instead, lazy evaluation isperformed: the first call to a non-timed wait function on the std::future that async returned to the caller will cause f(args...) to be executed in the currentthread. All further accesses to the same std::future will return the resultimmediately.
Smart Pointer
share_ptr
unique_ptr
weak_ptr
Regular Expression
To be continue....