C++03 vs. C++11: Fight!
in Programming on C++, Microsoft
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;
public:
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)) {}
#if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS)
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) {}
#endif
~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;
public:
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)) {}
#if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS)
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) {}
#endif
~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.