@interface AQBlog : NSBlog @end

Tutorials, musings on programming and ePublishing

C++03 vs. C++11: Fight!


In updating some stuff for the Readium SDK project, I wanted to use std::shared_ptr in some containers without lots of typing. Essentially I wanted something like shared_vector<SomeType> to magically unfold into vector<shared_ptr<SomeType>>.

Since I'm using C++11 for the project, that's actually pretty easy to do through the magic of template aliases:

template <class _Tp>
using shared_vector = std::vector<std::shared_ptr<_Tp>>;
template <class _Tp>
using shared_list = std::list<std::shared_ptr<_Tp>>;

Sadly, Microsoft's C++ compiler in Visual Studio 2012 doesn't support this syntax just yet, so I had to drop back to the C++03 implementation for that platform:

template <class _Tp>
class shared_vector : public std::vector<std::shared_ptr<_Tp>>
typedef std::vector<std::shared_ptr<_Tp>> _Base;
shared_vector() _NOEXCEPT_(std::is_nothrow_default_constructible<typename _Base::allocator_type>::value) : _Base() {}
explicit shared_vector(const typename _Base::allocator_type& __alloc) : _Base(__alloc) {}
explicit shared_vector(typename _Base::size_type __n) : _Base(__n) {}
shared_vector(typename _Base::size_type __n, const typename _Base::value_type& __v, const typename _Base::allocator_type& __a = typename _Base::allocator_type()) : _Base(__n, __v, __a) {}
template <class _InputIterator>
shared_vector(_InputIterator __f, _InputIterator __l, const typename _Base::allocator_type& __a = typename _Base::allocator_type()) : _Base(__f, __l, __a) {}
shared_vector(const shared_vector& __o) : _Base(__o) {}
shared_vector(shared_vector&& __o) : _Base(std::move(__o)) {}
shared_vector(std::initializer_list<typename _Base::value_type> __il) : _Base(__il) {}
shared_vector(std::initializer_list<typename _Base::value_type> __il, const typename _Base::allocator_type& __a) : _Base(__il, __a) {}
~shared_vector() { ~_Base(); }
shared_vector& operator=(const shared_vector& __o) { _Base::operator=(__o); return *this; }
shared_vector& operator=(shared_vector&& __o) { _Base::operator=(std::move(__o)); return *this; }
template <class _Tp>
class shared_list : public std::list<std::shared_ptr<_Tp>>
typedef std::list<std::shared_ptr<_Tp>> _Base;
shared_list() _NOEXCEPT_(std::is_nothrow_default_constructible<typename _Base::value_type>::value) : _Base() {}
explicit shared_list(const typename _Base::allocator_type& __a) : _Base(__a) {}
explicit shared_list(typename _Base::size_type __n) : _Base(__n) {}
shared_list(typename _Base::size_type __n, const typename _Base::value_type& __v) : _Base(__n, __v) {}
shared_list(typename _Base::size_type __n, const typename _Base::value_type& __v, const typename _Base::allocator_type& __a) : _Base(__n, __v, __a) {}
template <class _Iter>
shared_list(_Iter __f, _Iter __l) : _Base(__f, __l) {}
template <class _Iter>
shared_list(_Iter __f, _Iter __l, const typename _Base::allocator_type& __a) : _Base(__f, __l, __a) {}
shared_list(const shared_list& __o) : _Base(__o) {}
shared_list(shared_list&& __o) : _Base(std::move(__o)) {}
shared_list(std::initializer_list<typename _Base::value_type> __il) : _Base(__il) {}
shared_list(std::initializer_list<typename _Base::value_type> __il, const typename _Base::allocator_type& __a) : _Base(__il, __a) {}
~shared_list() { ~_Base(); }
shared_list& operator=(const shared_list& __o) { _Base::operator=(__o); return *this; }
shared_list& operator=(shared_list&& __o) { _Base::operator=(std::move(__o)); return *this; }

C++11 wins so hard it's not even funny.