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;
    
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.


© 2009-2019. All rights reserved.

Powered by Hydejack v8.5.2