Код состоит из следующего:
[ _Vector_impl ]: a std::allocator, который имитирует std::vector или контейнер stl, это наш собственный контейнер, хранящий ссылку на набор данных (входной массив или контейнер stl)
[ wrapRawArray ]: a функция для превращения array[] в наш собственный контейнер
[ ReleaseRawArray ]: функция для сброса _Vector_impl
[ ProxyContainer ]: ядро этого кусок кода. Это контейнер, который превращает массив в контейнер stl.
То, что делает этот ProxyContainer, выполняет роль прокси-сервера, то есть сохраняет ссылку на исходный набор данных (наш контейнер или массив в в этом случае), блокируя при этом прямую операцию с набором данных.
Код: Выделить всё
#include
#include
#include
using namespace std;
template
struct _Vector_base
{
struct _Vector_impl : public _Alloc
{
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
// etc
};
// etc
};
template
using vectorType = vector;
template
using vectorImpl = typename _Vector_base::_Vector_impl;
template
bool wrapRawArray(T(&_array)[N], vectorType* _container)
{
vectorImpl* vectImpl = (vectorImpl*)((void*)_container);
vectImpl->_M_start = _array;
vectImpl->_M_finish = vectImpl->_M_end_of_storage = vectImpl->_M_start + N;
return true;
}
template
void releaseRawArray(vectorType* _container) {
vectorImpl* vectImpl = (vectorImpl*)((void*)_container);
vectImpl->_M_finish = vectImpl->_M_end_of_storage = vectImpl->_M_start = nullptr;
}
template
class ProxyContainer
{
Container* container{ nullptr };
size_t size;
bool isRawArray{ false };
static string errorMessage;
public:
explicit ProxyContainer(Container& _container)
:container(&_container), size(_container.size()), isRawArray(false) {}
template
explicit ProxyContainer(T(&_array)[N])
:container(new Container) {
size = N;
isRawArray = wrapRawArray(_array, container);
}
~ProxyContainer() {
if (isRawArray) {
releaseRawArray(container);
if (container) {
delete container;
container = nullptr;
}
}
}
T& operator[](size_t index) {
if (index >= size) {
throw out_of_range(ProxyContainer::errorMessage
+ to_string(index));
}
return container->at(index);
}
void changeModel(Container& _container) {
container = &_container;
size = _container.size();
isRawArray = false;
}
};
template
string ProxyContainer::errorMessage{
"Attempt to use data out of range" };
int main()
{
// Raw array
int arr[] = { 1,2,3 };
ProxyContainer proxyForRawArray(arr);
proxyForRawArray[1] = 9;
cout
Подробнее здесь: [url]https://stackoverflow.com/questions/78695946/the-code-cannot-turn-array-into-my-custom-container-as-expected[/url]
Мобильная версия