c++ - Container that doesn't require its elements to be default and copy constructible -
i'm looking c++ container-like class wraps typed array of objects not initialized , don't have default-constructible or copy-constructible. interesting raii objects have no well-defined copy semantics. such container-like class seems easy write (using allocator allocate uninitialized memory , placement new). there in boost have overlooked? i'm not looking std::vector
(which requires elements copy-constructible) or pointer container, this:
#include <cstddef> #include <memory> #include <vector> #include <algorithm> #include <iostream> template< typename t, typename alloc = std::allocator<t> > class fixedvector { public: typedef typename alloc::value_type value_type; typedef typename alloc::pointer pointer; typedef typename alloc::reference reference; typedef typename alloc::const_pointer const_pointer; typedef typename alloc::const_reference const_reference; typedef typename alloc::size_type size_type; typedef typename alloc::difference_type difference_type; typedef pointer iterator; typedef const_pointer const_iterator; explicit fixedvector(size_type size, const alloc& allocator = alloc()): m_alloc(allocator), m_size(size), m_data(m_alloc.allocate(size)), m_constructed(size) { } fixedvector(const fixedvector& other): m_alloc(other.m_alloc), m_size(other.m_size), m_data(m_alloc.allocate(m_size)), m_constructed(other.m_constructed) { (size_type = 0; != m_size; ++i) { if (m_constructed[i]) m_alloc.construct(m_alloc.address(m_data[i]), other[i]); } } ~fixedvector() { (size_type = 0; != m_size; ++i) { if (m_constructed[i]) m_alloc.destroy(m_alloc.address(m_data[i])); } m_alloc.deallocate(m_data, m_size); } fixedvector& operator=(fixedvector other) { other.swap(*this); return *this; } // operator[] , other unimportant stuff void swap(fixedvector& other) { std::swap(m_alloc, other.m_alloc); std::swap(m_size, other.m_size); std::swap(m_data, other.m_data); std::swap(m_constructed, other.m_constructed); } void construct(size_type index) { new (m_alloc.address(m_data[index])) t(); m_constructed[index] = true; } template<typename u> void construct(size_type index, u& val) { new (m_alloc.address(m_data[index])) t(val); m_constructed[index] = true; } template<typename u> void construct(size_type index, const u& val) { new (m_alloc.address(m_data[index])) t(val); m_constructed[index] = true; } private: alloc m_alloc; size_type m_size; pointer m_data; std::vector<bool> m_constructed; }; template<typename t, typename alloc> void swap(fixedvector<t, alloc>& first, fixedvector<t, alloc>& second) { first.swap(second); } namespace std { template<typename t, typename alloc> void swap(fixedvector<t, alloc>& first, fixedvector<t, alloc>& second) { first.swap(second); } } class test { public: explicit test(int val): m_val(val) { std::cout << "test::test(" << val << ')' << std::endl; } ~test() { std::cout << "test::~test() [with m_val = " << m_val << ']' << std::endl; } int val() const { return m_val; } private: int m_val; test(const test&); test& operator=(const test&); }; template<typename char, typename traits> std::basic_ostream<char, traits>& operator<<(std::basic_ostream<char, traits>& stream, const test& object) { return stream << object.val(); } int main() { typedef fixedvector<test> fvt; fvt w(10); w.construct(7, 7); w.construct(2, 2); std::cout << "w[2] = " << w[2] << std::endl; }
the solution should work in c++03 (e.g. no move semantics allowed). question bit academical—i'm wondering why such class doesn't seem exist in boost.
such container-like class seems easy write (using allocator allocate uninitialized memory , placement new).
and std::vector
does. use placement new
, have make copy.
void store(const t& value) { new (storage) t(value); //<-- invokes copy constructor }
perhaps boost::ptr_vector work non-copyable types (you'd give pointers).
#include <boost/noncopyable.hpp> #include <boost/ptr_container/ptr_vector.hpp> #include <iostream> struct x: boost::noncopyable { x(int x): x(x) {} int x; }; int main() { boost::ptr_vector<x> vec; (int = 1; < 10; ++i) { vec.push_back(new x(i)); } (size_t = 0; != vec.size(); ++i) { std::cout << vec[i].x << '\n'; } }
and in c++0x, containers accept non-copyable types long movable (which should implementable non-copyable types).
Comments
Post a Comment