gpt4 book ai didi

c++ - 如何创建一个函数,返回一个 vector ,它使用自定义池分配器(如果提供),但默认为 std::allocator?

转载 作者:太空狗 更新时间:2023-10-29 20:00:01 25 4
gpt4 key购买 nike

在下面的代码中是函数 make_vector()。它创建一个 vector 并将其返回给调用者。我希望能够为要使用的 vector 指定一个分配器,但默认情况下使用默认的 std::allocator。这是因为在某些情况下,默认分配器就是我所需要的,但其他时候我需要从一些预定义的内存池中进行分配。

我最接近的是 make_vector2() 函数模板。它适用于 std::allocator,但我不知道如何将“arena”参数传递到我的自定义分配器中。

希望这个工作的 c++11 示例能更好地解释它:

#include <malloc.h>
#include <cinttypes>
#include <cstddef>
#include <iostream>
#include <limits>
#include <stdexcept>
#include <vector>

namespace mem
{
// Memory arena to allocate from.
enum class ARENA
{
TEXTURES,
FONTS,
SCRIPTS
};

// Allocate block from specific arena.
void *malloc( const std::size_t size, const ARENA arena )
{
return std::malloc( size /*, arena */ );
}

// Free block from specific arena.
void free( void *ptr, const ARENA arena )
{
std::free( ptr /*, arena */ );
}


// The allocator - forward declaration.
// Not derived from std::allocator - should it be?
// Based on code from here:
// http://drdobbs.com/184403759?pgno=2
template<typename T> class allocator;

// Specialised for void.
template<> class allocator<void>
{
public:
typedef std::size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;

template<typename U> struct rebind
{
typedef allocator<U> other;
};
};


template<typename T> class allocator
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;

template<typename U> struct rebind
{
typedef allocator<U> other;
};

allocator( ARENA arena ) noexcept :
arena_( arena )
{}

~allocator() noexcept
{}

pointer address( reference x ) const
{
return &x;
}

const_pointer address( const_reference x ) const
{
return &x;
}

pointer allocate( size_type n, allocator<void>::const_pointer hint = 0 )
{
void *p = mem::malloc( n * sizeof( T ), arena_ );
if ( p == nullptr )
{
throw std::bad_alloc();
}
return static_cast<pointer>( p );
}

void deallocate( pointer p, size_type n )
{
mem::free( p, arena_ );
}

size_type max_size() const noexcept
{
return std::numeric_limits<std::size_t>::max() / sizeof( T );
}

void construct( pointer p, const T& val )
{
new (p) T(val);
}

void destroy( pointer p )
{
p->~T();
}

allocator( const allocator& src ) noexcept
{
arena_ = src.arena_;
}

ARENA arena_;
};
} // namespace mem

template<class T1, class T2> bool operator==( const mem::allocator<T1> &alloc1, const mem::allocator<T2> &alloc2 ) noexcept
{
return alloc1.arena_ == alloc2.arena_;
}

template<class T1, class T2> bool operator!=( const mem::allocator<T1> &alloc1, const mem::allocator<T2> &alloc2 ) noexcept
{
if alloc1.arena_ != alloc2.arena_;
}

// How do I allow the custom allocator to be passed? Function parameter? Template?
std::vector<uint8_t> make_vector()
{
std::vector<uint8_t> vec;
// Do stuff with the vector
return vec;
}

// This template function seems to work with std::allocator
template< typename T > std::vector<uint8_t,T> make_vector2()
{
std::vector<uint8_t,T> vec;
// Do stuff with the vector.
return vec;
}

int main( int argc, char **argv )
{
// vec1 - Allocates from TEXTURES arena
// See the C++11 FAQ by Bjarne Stroustrup here:
// http://www2.research.att.com/~bs/C++0xFAQ.html#scoped-allocator
std::vector<uint8_t, mem::allocator<uint8_t>> vec1( mem::allocator<uint8_t>{mem::ARENA::TEXTURES} );

// vec2 - Make the vector using the default allocator.
auto vec2 = make_vector2< std::allocator<uint8_t> >();

return 0;
}

在 main() 中创建 vec1 以使用 TEXTURES arena 进行分配。要使用的竞技场被传递到分配器的构造函数中。 Vec2 由 make_vector2() 模板函数创建并使用 std::allocator。

问:我如何定义 make_vector() 函数,以便它可以创建一个使用上面的 std::allocator 或自定义池分配器的 vector ?

最佳答案

在 C++11 中,函数模板可以有默认的模板参数:

template<class T, class Alloc = std::allocator<T>>
std::vector<T, Alloc> make_vector(Alloc const& al = Alloc()){
std::vector<T, Alloc> v(al);
// ...
return v;
}

Live example on Ideone.

在C++03(或不支持该特性的编译器)中,它有点麻烦,但你可以基于模板参数重载:

template<class T>
std::vector<T> make_vector(){
std::vector<T> v;
// ...
return v;
}

template<class T, class Alloc>
std::vector<T, Alloc> make_vector(Alloc const& al = Alloc()){
std::vector<T, Alloc> v(al);
// ...
return v;
}

Live example on Ideone.

关于c++ - 如何创建一个函数,返回一个 vector ,它使用自定义池分配器(如果提供),但默认为 std::allocator?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9410826/

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