- Eliminate unnecessary expensive copies of user defined types (move semantics).
- Solve major usability problems with generic forwarding utilities (perfect forwarding).
- Solve usability problems in components where binding an rvalue to a non-const reference is not a logical error.
- in binder we want const lvalue references bind to both lvalue and rvalue while a non-const lvalue reference should bind only to non-const lvalue
template <class Operation> class binder2nd
public unary_function<...>
{ … public: … result_type operator()(const first_argument_type& x); result_type operator()( first_argument_type& x); };
template <class Operation> class binder2nd
public unary_function<...>
{ … public: … result_type operator()(first_argument_type&& x); };
template <class T> struct identity { typedef T type; };
template <class T> inline T&& forward(typename identity<T>::type&& t) // lvalue if T is an lvalue reference { return t; }
template <class T> inline typename remove_reference<T>::type&& move(T&& t) // always rvalue reference { return t; }
template <class T, class A1, class A2> shared_ptr<T> factory(A1&& a1, A2&& a2) { return shared_ptr<T>(new T(forward<A1>(a1), forward<A2>(a2))); }
struct A { A(int&, const double&); };
int main() { shared_ptr<A> sp1 = factory<A>(2, 1.414); // does not compile int i = 2; shared_ptr<A> sp2 = factory<A>(i, 1.414); // ok }
ClassName(ClassName&& src) { // copy pointers from src to this // set src pointers to null }
- protect against self assignment (as usually)
ClassName& operator= (ClassName&& src)…
also algos like random_shuffle, sort or remove_if can perform better with move semantics
template<class T> template<class Y, class D> shared_ptr<T>::shared_ptr(Y* p, D d); // D constructor must not throw! (or there is a memory leak)
template<class T> template<class Y, class D> shared_ptr<T>::shared_ptr(Y* p, const D& d);
but this makes d(p) is allowed to require non-const d
template<class T> template<class Y, class D> shared_ptr<T>::shared_ptr(Y* p, D& d);
but will not work for rvalue d
template<class T> template<class Y, class D> shared_ptr<T>::shared_ptr(Y* p, D&& d);
http://arcticinteractive.com/2008/11/29/brief-look-cpp0x-move-semantics-performance/
vector<A>().swap(v)
v.swap(vector<A>())
swap(v, vector<A>())
http://cpp-next.com/archive/2010/10/implicit-move-must-go/
its function-body shall be a compound-statement of the form { return expression; } where expression is a potential constant expression (5.19);
- defined constructor before usage
- empty function body of constructor
- all members initialized with constexprs
- trivial destructor
- should be copy-constexpr-able
- return type
- any member functions (including operators and constructors) can be a constexpr
- all arguments should be constexpr
- function called should be constexpr
- loops are not allowed (?)
constexpr bool little_endian() // DOES NOT WORK { const static unsigned num = 0xAABBCCDD; return reinterpret_cast<const unsigned char*> (&num)[0] == 0xDD; }
The expression involves an lvalue-to-rvalue conversion of the array reference, which is banned from constant expressions unless it is applied to an lvalue of effective integral type that refers to a non-volatile const variable or static data member initialized with constant expressions
const union { int int_value; char char_value[4]; } Endian = { 0xAABBCCDD };
constexpr bool little_endian() { return Endian[0] == 0xDD; }
Placing a value in a union then accessing the union via another member invokes undefined behaviour
template< typename Type > constexpr Type max( Type a, Type b ) { return a < b ? b : a; } // not sure about that one (args must be constexpr?)
can use numeric_limits<T>::max() as array size (if you have enough memory)
template <typename T, size_t N> constexpr size_t size_of(T (&)[N]) { return N; }
template<unsigned T> struct Fact { enum Enum { VALUE = Fact<T-1>*T; }; };
template<> struct Fact<1u> { enum Enum { VALUE = 1; }; };
int fact(unsigned n) { if (n==1) return 1; return fact(n-1)*n; }
- Has no nonstatic data members of type non-POD class/struct/union (or array of such types)
- Has a trivial default constructor. This may use the default constructor syntax (SomeConstructor() = default;).
- Has a trivial copy constructor, which may use the default syntax.
- Has a trivial copy assignment operator, which may use the default syntax.
- Has a trivial destructor, which must not be virtual.
draft says that all non-static members have the same access
struct { int x; public: int y; public: int z; };
Note that draft gives permission for the relative positions of b and c to be swapped (for classes/struct but what about PODs?) http://groups.google.com/group/comp.lang.c++.moderated/browse_frm/thread/1f21a3731a645cab/3f68c6bedded3ce5