I went to the C++ Tuturial with Herb Sutter and Bjarne Stroustrup.
Bjarne was once challenged by Adobe to explain why C++ succeeded for over 25 years with no cash or power. (As opposed to languages with millions of dollars and massive marketing machines like Java or C#.) He's humble, academic, and a true believer in his vision. He explained his success partially by solving only real-world problems and not getting wrapped up in any perfect solution. His goal was for C++ to be the second best at everything. (The best generally being hand-tweaked and optimized code.)
The namespace is currently std::tr1.
static_pointer_cast
dynamic_pointer_cast
const_pointer_cast
shared_from_this
with inheritance from enable_shared_from_this
when dealing with raw pointers that we know are really pointing to shared objects.weak_ptr
for breaking shared_ptr cycles. Lock before using.They mostly suck. (As compared to lambda.) But they do have their uses.
find_if(v.begin(), v.end(), bind(equal_to<string>(), bind(&person::name, _1), "Fred"));
A function wrapper. Can be used for the return value from a bind
. Also cleans code a little. Compare the following two:
pthread_once(pthread_once_t*, void(*)(void)); pthread_once(pthread_once_t*, function<void(void)>);
Just like in python.
Separates the generators (distribution settings) from the engines. Mix 'n Match 'em.
Bjarne presented a slide in “Speaking C++ as a Native” and in “C++0x” that presents bad use of C++ vs. better use and the impact on the runtime performance. It went something like this:
Bad Use
struct Link { Link * link; void * data; }; void my_clear(Link *p, int sz) { for (Link *q = p; q != 0; q = q->link) memset(q->data, 0, sz); }
Better Use
template<class In, class T> void my_stl_clear(forward_it first, forward_it last, const T &v) { while (first != last) *first++ = v; }
The idea here being that with type info, the compiler can optimize, inline and allow for caching far better than when having to deal with typeless (void) info. The object copy was on the order of 2 to 4x faster.
The gold standard in numbers crunching performance is Fortran, and Bjarne demonstrated how C++ can beat simple number crunching by providing the compiler with static type info to allow it to optimize cache usage. (Dense matrix arithmetric used.)
This also goes to the fact that we should prefer function objects over raw functions when using the STL.
Template constraints can be used to provide qualifying information for templates, and will help make error messages far more easy to read. Eg.,
template<class T> struct Comparable { static void constrants(T a, T b) { a<b; a<=b; } // constraint check Comparable() { void (*p)(T,T) = constrants; } // trigger the constraint }; template<class T> class Range : private Comparable<T>, ... { }; Range<int> r1; // ok Range<complex<double> > r2; // constraint error: no <
Bjarne gave an example of lambda. I gotta look into that more closely.
RAII, as always, got a lot of emphasis. Was used to decrease the number of occurances of try catch
loops too.
Provided as the solution to the common circle and triangle inherit from a stateful base shape class.
Sutter's concur project has some really interesting ideas. Keywords are active future parallel
and ordered
.
“A type system for C++ types.” Concepts help constrain templates to just those types to which they can apply.
template<Forward_iterator For, Value_type V> where Assignable<For::value_type, V> void fill(For first, For last, const V& v); // <-- just a declaration, not definition
template<class T> using Vec = vector<T,My_alloc<T>>; // like typedef, also note that >> is not an error! sort(v); // container, not two iterators! for(auto p = v.begin(); p != v.end(); ++p) cout << *p << endl; // auto! vector<double> v = { 1, 2, 3.4 }; // Initializer_list an object, can be returned, too!
Do the risky work off the the side, then commit with swap. (And benefit from C++0x's Rvalue construction!) RAII can sometimes be used to reduce the frequency of putting try catch
blocks everywhere.
Bjarne's too cute container assignment code:
template<class C> void safe_assign(C & a, const C b) { swap(a,b); }
enable_if
from Boost, it looks cool.catch (…)
is bad. (Unless you're at the interface to a module that cannot return exceptions.) E-mail the writer. Then put this up in the error section.