如何使 class 通过作用域分配器?
How do I make a class pass through scoped allocators?
我正在尝试让分配器感知 class,它可以在带有自定义分配器的向量中使用。 class 有一个 std::string 作为成员,我希望这个字符串像 class 一样用分配器分配。
如何让这样的分配器感知 class?下面的示例在 arena 上分配 class ClassA,但在默认分配器上分配 ClassA:mVarC。
using XAlloc1 = Allocator<char>;
using xstring = basic_string< char, char_traits<char>, XAlloc1 >;
template< typename Alloc = std::allocator<xstring> >
class ClassA : public Alloc {
public:
ClassA( xstring & str, Alloc & alloc )
: mVarA( int() ), mVarB( double() ), mVarC( str, alloc ) {
}
ClassA( xstring & str )
: mVarA( int() ), mVarB( double() ), mVarC( str ) {
}
int mVarA;
double mVarB;
xstring mVarC;
};
using XAlloc2 = scoped_allocator_adaptor< Allocator<xstring>,
Allocator<char> >;
using XClassA = ClassA< XAlloc2 >;
using XAlloc3 = scoped_allocator_adaptor< Allocator<XClassA>,
Allocator<xstring>,
Allocator<char> >;
using xvec = vector< XClassA, XAlloc3 > ;
void foo() {
MemoryPool<145> arena();
XAlloc3 alloc( arena );
xvec v( alloc );
v.emplace_back( XClassA( xstring( "Another very long text" ) ) );
}
为了制作 class 'allocator aware' 你必须
- 包含 'using allocator_type = Alloc;' 以便分配器可以查询它。
编写
的分配器版本
- 普通构造函数。 ClassA(const xstring & str, const Alloc & alloc)
- 复制构造函数。 ClassA(const ClassA & o, const Alloc & alloc)
- 移动构造函数。 ClassA(ClassA && o, const Alloc & alloc )
构造函数必须有一个'const Alloc &'参数作为尾随参数,
除非您指定 class 使用前导分配器参数。
- 普通构造函数。 ClassA(allocator_arg_t, const Alloc & alloc, const xstring & str )
- 复制构造函数。 ClassA( allocator_arg_t, const Alloc & alloc, const ClassA & o )
- 移动构造函数。 ClassA( allocator_arg_t, const Alloc & alloc, ClassA && o )
allocator_arg_t 未使用。它是一个空结构。 (不知道为什么一定要有,就是一定有。
.
template< typename Alloc = std::allocator<xstring> >
class ClassA {
public:
using allocator_type = Alloc;
ClassA( const xstring & str, const Alloc & alloc )
: mVarA( int() ), mVarB( double() ), mVarC( str, alloc ) { }
ClassA( const xstring & str )
: mVarA( int() ), mVarB( double() ), mVarC( str ) { }
ClassA( const ClassA & o, const Alloc & alloc )
: mVarA( o.mVarA ), mVarB( o.mVarB ), mVarC( o.mVarC, alloc ) { }
ClassA( const ClassA & o )
: VarA( o.mVarA ), mVarB( o.mVarB ), mVarC( o.mVarC ) { }
ClassA( ClassA && o, const Alloc & alloc )
: mVarA( move( o.mVarA ) ), mVarB( move( o.mVarB ) ), mVarC( move( o.mVarC ), alloc ) { }
ClassA( ClassA && o )
: mVarA( move( o.mVarA ) ), mVarB( move( o.mVarB ) ), mVarC( move( o.mVarC ) ) { }
int mVarA;
double mVarB;
xstring mVarC;
};
// // You can specify an allocator for each of the nested containers.
//using XAlloc2 = scoped_allocator_adaptor< Allocator<xstring>,
// Allocator<char> >;
//using XClassA = ClassA< XAlloc2 >;
//
//using XAlloc3 = scoped_allocator_adaptor< Allocator<XClassA>,
// Allocator<xstring>,
// Allocator<char> >;
//using xvec = vector< XClassA, XAlloc3 > ;
// Or you can just specify one allocator. This allocator will then be reused for all nested containers.
using XAlloc2 = scoped_allocator_adaptor< Allocator<xstring> >;
using XClassA = ClassA< XAlloc2 >;
using xvec = vector< XClassA, XAlloc2 >;
void funk() {
MemoryPool<145> arena();
XAlloc2 alloc( arena );
xvec v( alloc );
v.push_back( XClassA( xstring( "Another very long text" ) ) );
}
我正在尝试让分配器感知 class,它可以在带有自定义分配器的向量中使用。 class 有一个 std::string 作为成员,我希望这个字符串像 class 一样用分配器分配。
如何让这样的分配器感知 class?下面的示例在 arena 上分配 class ClassA,但在默认分配器上分配 ClassA:mVarC。
using XAlloc1 = Allocator<char>;
using xstring = basic_string< char, char_traits<char>, XAlloc1 >;
template< typename Alloc = std::allocator<xstring> >
class ClassA : public Alloc {
public:
ClassA( xstring & str, Alloc & alloc )
: mVarA( int() ), mVarB( double() ), mVarC( str, alloc ) {
}
ClassA( xstring & str )
: mVarA( int() ), mVarB( double() ), mVarC( str ) {
}
int mVarA;
double mVarB;
xstring mVarC;
};
using XAlloc2 = scoped_allocator_adaptor< Allocator<xstring>,
Allocator<char> >;
using XClassA = ClassA< XAlloc2 >;
using XAlloc3 = scoped_allocator_adaptor< Allocator<XClassA>,
Allocator<xstring>,
Allocator<char> >;
using xvec = vector< XClassA, XAlloc3 > ;
void foo() {
MemoryPool<145> arena();
XAlloc3 alloc( arena );
xvec v( alloc );
v.emplace_back( XClassA( xstring( "Another very long text" ) ) );
}
为了制作 class 'allocator aware' 你必须
- 包含 'using allocator_type = Alloc;' 以便分配器可以查询它。
编写
的分配器版本- 普通构造函数。 ClassA(const xstring & str, const Alloc & alloc)
- 复制构造函数。 ClassA(const ClassA & o, const Alloc & alloc)
- 移动构造函数。 ClassA(ClassA && o, const Alloc & alloc )
构造函数必须有一个'const Alloc &'参数作为尾随参数, 除非您指定 class 使用前导分配器参数。
- 普通构造函数。 ClassA(allocator_arg_t, const Alloc & alloc, const xstring & str )
- 复制构造函数。 ClassA( allocator_arg_t, const Alloc & alloc, const ClassA & o )
- 移动构造函数。 ClassA( allocator_arg_t, const Alloc & alloc, ClassA && o )
allocator_arg_t 未使用。它是一个空结构。 (不知道为什么一定要有,就是一定有。
.
template< typename Alloc = std::allocator<xstring> >
class ClassA {
public:
using allocator_type = Alloc;
ClassA( const xstring & str, const Alloc & alloc )
: mVarA( int() ), mVarB( double() ), mVarC( str, alloc ) { }
ClassA( const xstring & str )
: mVarA( int() ), mVarB( double() ), mVarC( str ) { }
ClassA( const ClassA & o, const Alloc & alloc )
: mVarA( o.mVarA ), mVarB( o.mVarB ), mVarC( o.mVarC, alloc ) { }
ClassA( const ClassA & o )
: VarA( o.mVarA ), mVarB( o.mVarB ), mVarC( o.mVarC ) { }
ClassA( ClassA && o, const Alloc & alloc )
: mVarA( move( o.mVarA ) ), mVarB( move( o.mVarB ) ), mVarC( move( o.mVarC ), alloc ) { }
ClassA( ClassA && o )
: mVarA( move( o.mVarA ) ), mVarB( move( o.mVarB ) ), mVarC( move( o.mVarC ) ) { }
int mVarA;
double mVarB;
xstring mVarC;
};
// // You can specify an allocator for each of the nested containers.
//using XAlloc2 = scoped_allocator_adaptor< Allocator<xstring>,
// Allocator<char> >;
//using XClassA = ClassA< XAlloc2 >;
//
//using XAlloc3 = scoped_allocator_adaptor< Allocator<XClassA>,
// Allocator<xstring>,
// Allocator<char> >;
//using xvec = vector< XClassA, XAlloc3 > ;
// Or you can just specify one allocator. This allocator will then be reused for all nested containers.
using XAlloc2 = scoped_allocator_adaptor< Allocator<xstring> >;
using XClassA = ClassA< XAlloc2 >;
using xvec = vector< XClassA, XAlloc2 >;
void funk() {
MemoryPool<145> arena();
XAlloc2 alloc( arena );
xvec v( alloc );
v.push_back( XClassA( xstring( "Another very long text" ) ) );
}