gpt4 book ai didi

c++ - 不需要其元素是默认元素和可复制构造的容器

转载 作者:行者123 更新时间:2023-11-30 01:31:16 24 4
gpt4 key购买 nike

我正在寻找一个类似 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 中似乎不存在这样的类。

最佳答案

Such a container-like class seems to be fairly easy to write (using an allocator to allocate uninitialized memory and placement new).

而这正是 std::vector 所做的。要使用展示位置 new,您必须复制一份。

void store(const T& value)
{
new (storage) T(value); //<-- invokes copy constructor
}

也许 boost::ptr_vector 可以用于不可复制的类型(你会给它指点)。

#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;
for (int i = 1; i < 10; ++i) {
vec.push_back(new X(i));
}

for (size_t i = 0; i != vec.size(); ++i) {
std::cout << vec[i].x << '\n';
}
}

在 C++0x 中,容器将接受不可复制的类型,只要它们是可移动的(对于不可复制的类型,这通常应该是可实现的)。

关于c++ - 不需要其元素是默认元素和可复制构造的容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3329281/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com