© Copyright SELA software & Education Labs Ltd. 14-18 Baruch Hirsch St.Bnei Brak 51202 Israel
                                      www.sela.co.il
Variadic Templates
Concepts
Other Wild Ideas
• Visual Studio 2010: Some features are supported
• Visual Studio 2012: Some more features are supported




                                                                          Not supported yet
                                       Visual Studio 2012
     Visual Studio 2010




                          Automatic                         Concurrency                       Variadic
                          variables,                        library                           templates
                          decltype                          Memory                            Custom
                          Rvalue                            model                             literals
                          references                                                          Delegating
                          Lambda                                                              constructors
                          functions
• Comparison chart between many other compilers:
  http://s.sashag.net/rpST0u
The problem with existing templates is that the
  number of parameters is constant, consider:
      tuple, printf, other type-safe va_list, …

template <typename T1> struct tuple {
  T1 first;
};
template <typename T1, typename T2> struct tuple {
  T1 first; T2 second;
};
template <typename T1, typename T2, typename T3> struct tuple {
  T1 first; T2 second; T3 third;
};
//VC11 <tuple> does this with macros, going up to 10 parameters
New syntax for unbounded type parameter lists and
  function parameter lists
      “Dot-dot-dot is where the fun begins”

template <typename... Ts>
void foo(Ts&&... vs); //note: Ts is NOT a type, vs is NOT a variable

foo(42);                        foo(5, "Hello, World", vector<int>());

template <typename... Ts>
struct tuple; //requires some serious work!

tuple<int, float, string> tup(42, 42.0f, "42");
get<1>(tup) += 3.0f;             cout << get<2>(tup) << endl;
New syntax for type list expansion
      …and there’s also a new operator: sizeof...()


template <typename... Ts>
int passthrough_printf(const char* fmt, Ts&&... vs)
  return printf(fmt, vs...);
}
template <typename... Ts>
class mixin : public Ts... {}; //will inherit from all Ts specified

//note: the following two statements ARE NOT THE SAME!
foo(goo(vs...));    ≡ foo(goo(v1, v2, v3));
foo(goo(vs)...);    ≡ foo(goo(v1), goo(v2), goo(v3));
Typically, you have a base case that does something (or
  nothing) and “recurse” to it from the variadic case
      Not true recursion (different template)

template <typename... Ts>
void print(Ts&&... vs) {} //base case, will match empty list, do nothing

template <typename T, typename... Ts>
void print(T&& v, Ts&&... vs) {
  cout << v << endl;
  print(vs...); //”recursive” case; note that any decent compiler
}               //will inline the whole thing into the caller
Alternatively, the base case can be a bounded number
  of parameters to which we “recurse”


template <typename T1, typename T2>
bool assertContained(T1&& v1, T2&& v2) {
  return v1 == v2;
}

template <typename T1, typename T2, typename... Ts>
bool assertContained(T1&& v1, T2&& v2, Ts&&... vs) {
  return (v1 == v2 || assertContained(v1, vs...));
}
Using the compiler’s template mechanism to do work
  at compile-time
     Theorem: C++ templates are Turing-complete

//recursive case:
template <int N> struct fibo {
  static const int value = fibo<N-1>::value + fibo<N-2>::value;
};
//base cases:
template <> struct fibo<0> { static const int value = 1; };
template <> struct fibo<1> { static const int value = 1; };

cout << fibo<14>::value; //compile-time!
template <typename T> void print(const T& t) {}
template <typename T> void print(const T& t,
  typename enable_if<
    is_pointer<T>::value, void*
  >::type dummy = nullptr) {         From <type_traits>
  printf("%p", t);                   (simple specializations)
}
template <typename T> void print(const T& t,
  typename enable_if<
    is_convertible<T,string>::value, void*     template <
                                                bool, typename T = void
  >::type dummy = nullptr) {
                                               >
  printf("%s", string(t).c_str());             struct enable_if {};
}
                                                template <typename T>
                                                struct enable_if<true,T> {
                                                  typedef T type;
                                                };
We now develop a partial tuple<...>
     (Practically) No limit on number of type parameters
     Following A. Alexandrescu’s GoingNative 2012 talk

template <typename... Ts> struct tuple {};
template <typename T, typename... Ts>
struct tuple : private tuple<Ts...> {
  T _head;
public:
  tuple(T&& v, Ts&&... vs) :
    _head(v), tuple<Ts...>(vs...) {}
  //many more methods omitted
};
• Note that tuple<T1,T2> derives from tuple<T2>
     tuple<>           tuple<>          tuple<>
     (empty)           (empty)          (empty)
                      tuple<T1>        tuple<T2>
                       T1 _head        T2 _head
 tuple(T1 v):                        tuple<T1,T2>
   _head(v)
                                       T1 _head
         tuple(T1 v, T2 v2):
           _head(v), tuple<T2>(v2)
We need a way to declare the type of the k-th element
     The get<N>() method will return it (later)


template <int, typename> struct tuple_elem;
template <typename T, typename... Ts>
struct tuple_elem<0, tuple<T,Ts...>> {
  typedef T type; //this is the head, base case
};
template <int k, typename T, typename Ts...>
struct tuple_elem<k, tuple<T,Ts...>> {
  typedef tuple_elem<k-1,Ts...>::type type; //recursion
};
template <int k, typename Ts...>
typename enable_if<k==0,
  typename tuple_elem<k,Ts...>::type&>::type
get(tuple<Ts...>& tuple) {
  return tuple._head;                            Why not a member
} //base case                                    function on tuple?

template <int k, typename T, typename Ts...>
typename enable_if<k!=0,
  typename tuple_elem<k,T,Ts...>::type&>::type
get(tuple<T,Ts...>& tuple) {
  tuple<Ts...>& base = tuple;
  get<k-1>(base); //recursion
}
tuple<int, float, string, employee> tup(...);
get<0>(tup) = 42;
get<3>(tup) = employee("John");
cout << get<3>(tup).name() << endl;

//Worth the effort. C# doesn’t have unlimited tuples!
//…and here’s another cool thing, Python-style:

tuple<int,bool> get_something() { ... }
                                           How does this work?
int number; bool flag;                     tuple<T1&,T2&,…>
std::tie(number, flag) = get_something();
//now number, flag are the unpacked tuple!
• Primary concern: improve compiler errors
   In file included from c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:65:0,
               from c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/map:60,
               from ConceptsMotivation.cpp:2:
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_function.h: In member function 'bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = non_comparable]':
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_map.h:452:2: instantiated from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const
   key_type&) [with _Key = non_comparable, _Tp = int, _Compare = std::less<non_comparable>, _Alloc = std::allocator<std::pair<const non_comparable, int> >, std::map<_Key, _Tp, _Compare,
   _Alloc>::mapped_type = int, std::map<_Key, _Tp, _Compare, _Alloc>::key_type = non_comparable]'
   ConceptsMotivation.cpp:8:20: instantiated from here
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_function.h:236:22: error: no match for 'operator<' in '__x < __y'
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_function.h:236:22: note: candidates are:
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_pair.h:207:5: note: template<class _T1, class _T2> bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:291:5: note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const
   std::reverse_iterator<_Iterator>&)
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:341:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_IteratorL>&, const
   std::reverse_iterator<_IteratorR>&)
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:856:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator<(const std::_Rb_tree<_Key,
   _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_map.h:894:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::map<_Key, _Tp, _Compare, _Alloc>&,
   const std::map<_Key, _Tp, _Compare, _Alloc>&)
   c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_multimap.h:812:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::multimap<_Key, _Tp, _Compare,
   _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&)




• Secondary: optimizations, better specialization, etc.
• Future feature: NOT PART OF C++ 11
The language compiler verifies that the generic type
  performs only operations that are guaranteed to exist
  on its type parameters
     Limited set of constraints: base class, interface,
     parameterless constructor

class SortedList<T> where T : IComparable<T> {
  private T[] items;
  public void Add(T item) {
    //...can use item.CompareTo(otherItem) here
  }
}
New keyword (concept)
  Looks like a template class with no implementation

auto concept CopyConstructible<typename T> {
  T(const T&);
};
auto concept Comparable<typename T> {
  bool operator<(T, T);
};
auto concept Convertible<typename T, typename S> {
  operator S(const T&);
};
To assert that a concept is available, use requires
  Can specialize templates on concept requirements


template <typename T> requires LessThanComparable<T>
void sort(T* data, int length) { ... }

//instead of SFINAE:
template <typename T>
  requires !LessThanComparable<T> && GreaterThanComparable<T>
void sort(T* data, int length) { ... }
Concepts can require other concepts
  Concepts can derive from other concepts

concept InputIterator<typename Iter, typename Elem> {
   requires CopyConstructible<Iter>;
   Elem operator*(const Iter&);
   Iter operator++(Iter&, int);
};
concept ForwardIterator<typename Iter, typename Elem>
   : InputIterator<Iter, Value> {
   //additional requirements
};
Specify how to bind a concept to an existing type
     E.g., vector<T> was not designed to adhere to a stack
     concept, but can be adapted after the fact

concept stack<typename C, typename T> {
  void push(C&, const T&);
  bool pop(C&, T&);
};
template <typename T> concept_map stack<vector<T>> {
  void push(vector<T>& v, const T& t) { v.push_back(t); }
  bool pop(vector<T>& v, T& t) { ... }
};
• enable_if “[…] is marred by a baroque syntax,
  frequent and nontrivial corner cases, and interference
  of mechanism with the exposed interface.”
   – N3329 (draft proposal for static_if)
• Currently impossible to:
   – Define a class member conditionally
   – Easily share code between specializations
   – Mix case-specific code within the same function
template <typename T>
void print(const T& t) {
  static_if (is_integral<T>::value) {
    printf("%d", (unsigned long long)t);
  } else {
    static_if (is_pointer<T>::value) {
      printf("%p", t);
    }
    else {
      static_assert(false, "Unsupported type");
    }
  }
}
template <int N>
struct factorial { //remember fibo?
  static_if (N <= 1) {
    enum { value = 1 };
  } else {
    enum { value = factorial<N-1>::value * N };
  }
};

//can replace many uses of concepts:
template <typename T> void sort(...)
if (has_operator_less_than<T>::value) { ... }
Proposal N3361 based on Intel Cilk
  cilk_spawn, cilk_sync, cilk_for keywords
     Akin to similar OpenMP pragmas
     Additional suggestions for SIMD-friendly operators, such as
     array slices and #pragma simd

cilk_for (auto c = customers.begin();
          c != customers.end(); ++c) {
  consider_vip_status(c);
  adjust_discount(c);
}
Mirroring the success of C# 5’s await operator
  Breaks down the method into a synchronous part and
  one or more continuations
future<vector<image*>> download_profile_images(
                              vector<user> users) {
  vector<image*> images;
  webclient wc;
  for (const auto& user : users)
    images.push_back(new image(
      await wc.download(user.profile_image_url()));
  return images;
}
Transactional language constructs on top of software
  transactional memory (N3341)
     (By the way, Intel Haswell will have hardware TX semantics)

class Account {
  void withdraw(int amount) {
    __transaction { balance -= amount; }
  }
};
void transfer(Account& a, Account& b, int amount) {
  __transaction {
    a.withdraw(amount); b.deposit(amount);
  }
}
Variadic Templates
Concepts
Other Wild Ideas
Many more at the ISO C++ WG
The Future of C++

The Future of C++

  • 1.
    © Copyright SELAsoftware & Education Labs Ltd. 14-18 Baruch Hirsch St.Bnei Brak 51202 Israel www.sela.co.il
  • 2.
  • 3.
    • Visual Studio2010: Some features are supported • Visual Studio 2012: Some more features are supported Not supported yet Visual Studio 2012 Visual Studio 2010 Automatic Concurrency Variadic variables, library templates decltype Memory Custom Rvalue model literals references Delegating Lambda constructors functions • Comparison chart between many other compilers: http://s.sashag.net/rpST0u
  • 4.
    The problem withexisting templates is that the number of parameters is constant, consider: tuple, printf, other type-safe va_list, … template <typename T1> struct tuple { T1 first; }; template <typename T1, typename T2> struct tuple { T1 first; T2 second; }; template <typename T1, typename T2, typename T3> struct tuple { T1 first; T2 second; T3 third; }; //VC11 <tuple> does this with macros, going up to 10 parameters
  • 5.
    New syntax forunbounded type parameter lists and function parameter lists “Dot-dot-dot is where the fun begins” template <typename... Ts> void foo(Ts&&... vs); //note: Ts is NOT a type, vs is NOT a variable foo(42); foo(5, "Hello, World", vector<int>()); template <typename... Ts> struct tuple; //requires some serious work! tuple<int, float, string> tup(42, 42.0f, "42"); get<1>(tup) += 3.0f; cout << get<2>(tup) << endl;
  • 6.
    New syntax fortype list expansion …and there’s also a new operator: sizeof...() template <typename... Ts> int passthrough_printf(const char* fmt, Ts&&... vs) return printf(fmt, vs...); } template <typename... Ts> class mixin : public Ts... {}; //will inherit from all Ts specified //note: the following two statements ARE NOT THE SAME! foo(goo(vs...)); ≡ foo(goo(v1, v2, v3)); foo(goo(vs)...); ≡ foo(goo(v1), goo(v2), goo(v3));
  • 7.
    Typically, you havea base case that does something (or nothing) and “recurse” to it from the variadic case Not true recursion (different template) template <typename... Ts> void print(Ts&&... vs) {} //base case, will match empty list, do nothing template <typename T, typename... Ts> void print(T&& v, Ts&&... vs) { cout << v << endl; print(vs...); //”recursive” case; note that any decent compiler } //will inline the whole thing into the caller
  • 8.
    Alternatively, the basecase can be a bounded number of parameters to which we “recurse” template <typename T1, typename T2> bool assertContained(T1&& v1, T2&& v2) { return v1 == v2; } template <typename T1, typename T2, typename... Ts> bool assertContained(T1&& v1, T2&& v2, Ts&&... vs) { return (v1 == v2 || assertContained(v1, vs...)); }
  • 9.
    Using the compiler’stemplate mechanism to do work at compile-time Theorem: C++ templates are Turing-complete //recursive case: template <int N> struct fibo { static const int value = fibo<N-1>::value + fibo<N-2>::value; }; //base cases: template <> struct fibo<0> { static const int value = 1; }; template <> struct fibo<1> { static const int value = 1; }; cout << fibo<14>::value; //compile-time!
  • 10.
    template <typename T>void print(const T& t) {} template <typename T> void print(const T& t, typename enable_if< is_pointer<T>::value, void* >::type dummy = nullptr) { From <type_traits> printf("%p", t); (simple specializations) } template <typename T> void print(const T& t, typename enable_if< is_convertible<T,string>::value, void* template < bool, typename T = void >::type dummy = nullptr) { > printf("%s", string(t).c_str()); struct enable_if {}; } template <typename T> struct enable_if<true,T> { typedef T type; };
  • 11.
    We now developa partial tuple<...> (Practically) No limit on number of type parameters Following A. Alexandrescu’s GoingNative 2012 talk template <typename... Ts> struct tuple {}; template <typename T, typename... Ts> struct tuple : private tuple<Ts...> { T _head; public: tuple(T&& v, Ts&&... vs) : _head(v), tuple<Ts...>(vs...) {} //many more methods omitted };
  • 12.
    • Note thattuple<T1,T2> derives from tuple<T2> tuple<> tuple<> tuple<> (empty) (empty) (empty) tuple<T1> tuple<T2> T1 _head T2 _head tuple(T1 v): tuple<T1,T2> _head(v) T1 _head tuple(T1 v, T2 v2): _head(v), tuple<T2>(v2)
  • 13.
    We need away to declare the type of the k-th element The get<N>() method will return it (later) template <int, typename> struct tuple_elem; template <typename T, typename... Ts> struct tuple_elem<0, tuple<T,Ts...>> { typedef T type; //this is the head, base case }; template <int k, typename T, typename Ts...> struct tuple_elem<k, tuple<T,Ts...>> { typedef tuple_elem<k-1,Ts...>::type type; //recursion };
  • 14.
    template <int k,typename Ts...> typename enable_if<k==0, typename tuple_elem<k,Ts...>::type&>::type get(tuple<Ts...>& tuple) { return tuple._head; Why not a member } //base case function on tuple? template <int k, typename T, typename Ts...> typename enable_if<k!=0, typename tuple_elem<k,T,Ts...>::type&>::type get(tuple<T,Ts...>& tuple) { tuple<Ts...>& base = tuple; get<k-1>(base); //recursion }
  • 15.
    tuple<int, float, string,employee> tup(...); get<0>(tup) = 42; get<3>(tup) = employee("John"); cout << get<3>(tup).name() << endl; //Worth the effort. C# doesn’t have unlimited tuples! //…and here’s another cool thing, Python-style: tuple<int,bool> get_something() { ... } How does this work? int number; bool flag; tuple<T1&,T2&,…> std::tie(number, flag) = get_something(); //now number, flag are the unpacked tuple!
  • 16.
    • Primary concern:improve compiler errors In file included from c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:65:0, from c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/map:60, from ConceptsMotivation.cpp:2: c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_function.h: In member function 'bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = non_comparable]': c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_map.h:452:2: instantiated from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = non_comparable, _Tp = int, _Compare = std::less<non_comparable>, _Alloc = std::allocator<std::pair<const non_comparable, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int, std::map<_Key, _Tp, _Compare, _Alloc>::key_type = non_comparable]' ConceptsMotivation.cpp:8:20: instantiated from here c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_function.h:236:22: error: no match for 'operator<' in '__x < __y' c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_function.h:236:22: note: candidates are: c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_pair.h:207:5: note: template<class _T1, class _T2> bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:291:5: note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&) c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:341:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&) c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:856:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator<(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&) c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_map.h:894:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::map<_Key, _Tp, _Compare, _Alloc>&, const std::map<_Key, _Tp, _Compare, _Alloc>&) c:mingwbin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_multimap.h:812:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::multimap<_Key, _Tp, _Compare, _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&) • Secondary: optimizations, better specialization, etc. • Future feature: NOT PART OF C++ 11
  • 17.
    The language compilerverifies that the generic type performs only operations that are guaranteed to exist on its type parameters Limited set of constraints: base class, interface, parameterless constructor class SortedList<T> where T : IComparable<T> { private T[] items; public void Add(T item) { //...can use item.CompareTo(otherItem) here } }
  • 18.
    New keyword (concept) Looks like a template class with no implementation auto concept CopyConstructible<typename T> { T(const T&); }; auto concept Comparable<typename T> { bool operator<(T, T); }; auto concept Convertible<typename T, typename S> { operator S(const T&); };
  • 19.
    To assert thata concept is available, use requires Can specialize templates on concept requirements template <typename T> requires LessThanComparable<T> void sort(T* data, int length) { ... } //instead of SFINAE: template <typename T> requires !LessThanComparable<T> && GreaterThanComparable<T> void sort(T* data, int length) { ... }
  • 20.
    Concepts can requireother concepts Concepts can derive from other concepts concept InputIterator<typename Iter, typename Elem> { requires CopyConstructible<Iter>; Elem operator*(const Iter&); Iter operator++(Iter&, int); }; concept ForwardIterator<typename Iter, typename Elem> : InputIterator<Iter, Value> { //additional requirements };
  • 21.
    Specify how tobind a concept to an existing type E.g., vector<T> was not designed to adhere to a stack concept, but can be adapted after the fact concept stack<typename C, typename T> { void push(C&, const T&); bool pop(C&, T&); }; template <typename T> concept_map stack<vector<T>> { void push(vector<T>& v, const T& t) { v.push_back(t); } bool pop(vector<T>& v, T& t) { ... } };
  • 22.
    • enable_if “[…]is marred by a baroque syntax, frequent and nontrivial corner cases, and interference of mechanism with the exposed interface.” – N3329 (draft proposal for static_if) • Currently impossible to: – Define a class member conditionally – Easily share code between specializations – Mix case-specific code within the same function
  • 23.
    template <typename T> voidprint(const T& t) { static_if (is_integral<T>::value) { printf("%d", (unsigned long long)t); } else { static_if (is_pointer<T>::value) { printf("%p", t); } else { static_assert(false, "Unsupported type"); } } }
  • 24.
    template <int N> structfactorial { //remember fibo? static_if (N <= 1) { enum { value = 1 }; } else { enum { value = factorial<N-1>::value * N }; } }; //can replace many uses of concepts: template <typename T> void sort(...) if (has_operator_less_than<T>::value) { ... }
  • 25.
    Proposal N3361 basedon Intel Cilk cilk_spawn, cilk_sync, cilk_for keywords Akin to similar OpenMP pragmas Additional suggestions for SIMD-friendly operators, such as array slices and #pragma simd cilk_for (auto c = customers.begin(); c != customers.end(); ++c) { consider_vip_status(c); adjust_discount(c); }
  • 26.
    Mirroring the successof C# 5’s await operator Breaks down the method into a synchronous part and one or more continuations future<vector<image*>> download_profile_images( vector<user> users) { vector<image*> images; webclient wc; for (const auto& user : users) images.push_back(new image( await wc.download(user.profile_image_url())); return images; }
  • 27.
    Transactional language constructson top of software transactional memory (N3341) (By the way, Intel Haswell will have hardware TX semantics) class Account { void withdraw(int amount) { __transaction { balance -= amount; } } }; void transfer(Account& a, Account& b, int amount) { __transaction { a.withdraw(amount); b.deposit(amount); } }
  • 28.
    Variadic Templates Concepts Other WildIdeas Many more at the ISO C++ WG

Editor's Notes

  • #6 Not supported by VC11.To show the demo, use MinGW or any other gcc-clone (gcc 4.6.2 or higher is known to work).The quote (“dot dotdot is where the fun begins”) is from Andrei Alexandrescu’s talk at GoingNative 2012: http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Variadic-Templates-are-Funadic
  • #19 This is not up to date with the most recent proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf