我正在尋找一個C++容器類的類包裝對象的類型化數組,不一定是初始化的,並且不必是默認構造的或可複製構造。對於沒有明確定義的複製語義的RAII對象來說,這會很有趣。這樣一個類似容器的類似乎很容易編寫(使用分配器來分配未初始化的內存和放置新的)。我剛剛忽略了Boost中是否有這樣的內容?我不是在尋找std::vector
(這要求它的元素是拷貝構造)或指針容器,但這樣的事情:不需要其元素的容器默認和複製可構造
#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) {
for (size_type i = 0; i != m_size; ++i) {
if (m_constructed[i]) m_alloc.construct(m_alloc.address(m_data[i]), other[i]);
}
}
~FixedVector() {
for (size_type i = 0; i != 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[] and 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;
}
解決辦法應該工作在C++ 03(例如,沒有移動語義允許)。這個問題有點學術性 - 我只是想知道爲什麼這樣一個類似乎不存在於Boost中。
請注意,您有一個非常奇怪的'operator ='那裏。 – UncleBens 2010-07-25 13:40:59
@UncleBens:爲什麼? – Philipp 2010-07-25 14:26:00
對不起,沒有注意到這個參數是按值傳遞的。 (作業仍然與手邊的問題無關:當存儲類型不可複製時,您無法分配/複製FixedVector。) – UncleBens 2010-07-25 14:40:34