Going Native 2013
Herb Sutter had a couple of favorite C++ few-liners. Watch the video here: My Favorite C++ 10-liner.
A complete reference-counted object cache.
From C++98 it uses map operator[]'s auto-insertion.
From C++11 it uses:
- auto
- mutex, lock_guard
- Thread-safe fn statics
- shared_ptr and weak_ptr
- Thread-safe.lock()
- widget_cache.cpp
shared_ptr<widget> get_widget( int id ) { static map< int, weak_ptr<widget> > cache; static mutex m; lock_guard<mutex> hold(m); auto sp = cache[id].lock(); // cache[id] returns a weak_ptr. lock() returns the shared_ptr if( !sp ) cache[id] = sp = load_widget(id); return sp; }
In C++11, the following code is thread safe! It's the Meyers Singleton.
- Thread safe fn statics
- Does destruction. No need for Alexandrescu's various destruction policies anymore!
- thread_safe_meyers_singleton.cpp
widget& instance() { static widget w; return w; }
This one uses the Cinder C++ Library.
- gui_app.cpp
#include "cinder/app/AppBasic.h" #include "cinder/dx/dx.h" #include <vector> using namespace ci; using namespace ci::app; class MyApp:public AppBasic { std::vector< Vec2f > points; public: void mouseDrag( MouseEvent e ) { points.push_back( e.getPos() ); } void draw() { dx::clear( Color( 0.1f, 0.1f, 0.15f ) ); dx::color( 1.0f, 0.5f, 0.25f ); dx::begin( GL_LINE_STRIP ); for( auto& e: points ) dx::vertex( e ); dx::end(); } }; CINDER_APP_BASIC( MyApp, RendererDx )
Advanced Optimization
Use lambda in place of std::bind to save memory. A std::bind() on a pointer-to-member-function will allocate 24 bytes on the heap for the bind structure. If instead you use a lambda, then this fits into 4 bytes and avoids any allocation.
Replace:
g(this, std::bind(&m_f, this)),
With:
g(this, [this](){this->m_f();}),
Note that subtle changes to object lifetimes is possible. This code:
std::bind(f, std::weak_ptr<Object>(n));
is not the same as this code:
[n]{ f(std::weak_ptr<Object>(n)); }
The above code will bind the shared_ptr<Node> into the lambda's capture, extending the lifetime.
But it is the same as this:
[wp = std::weak_ptr<Object>(n)]{ f(wp); };
In this case the lambda's capture only has the weak pointer.