change or use the same allocator with private member inside a class

88 views
Skip to first unread message

ken...@googlemail.com

unread,
Dec 8, 2012, 5:04:36 AM12/8/12
to

Hello, if I have a different allocator, can I use that allocator to
allocate memory with vector or string as private member? How so?

actual code:

#ifndef COMMAND_LINE_H
#define COMMAND_LINE_H

namespace bos {

//template<typename Allocator = std::allocator<T>>
class basic_command_line {
public:
basic_command_line(int argc, char * argv[]);
basic_command_line(const command_line& other) = delete;
basic_command_line & operator=(const command_line& other) = delete;
basic_command_line(const command_line&& other) = delete;
basic_command_line & operator=(const command_line&& other) = delete;
void print() const;
~basic_command_line();
private:
std::vector<std::string> args_;
//std::vector<std::string<Allocater<char>,
Allocator<std::string>> args_;
};

typedef basic_command_line command_line;

}

#endif


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Tobias Müller

unread,
Dec 8, 2012, 8:32:51 AM12/8/12
to

<ken...@googlemail.com> wrote:
> Hello, if I have a different allocator, can I use that allocator to
> allocate memory with vector or string as private member? How so?
>
> actual code:
>
> #ifndef COMMAND_LINE_H
> #define COMMAND_LINE_H
>
> namespace bos {
>
> //template<typename Allocator = std::allocator<T>>

What is T?
It's not possible to use the same concrete allocator for two different
types.

If you are sure, that you only use trait-style allocators (i.e. all your
custom allocators are templates), you can make the 'Allocator' template
parameter itself a template:

template <template<class> class Allocator = std::allocator>

Or since you already know the member types you are using you could specify
them directly:

template <class AllocChar = std::allocator<char>, class AllocString =
std::allocator<std::basic_string<char, std::char_traits<char>, AllocChar> >
>

> class basic_command_line {
> public:
> basic_command_line(int argc, char * argv[]);
> basic_command_line(const command_line& other) = delete;
> basic_command_line & operator=(const command_line& other) = delete;
> basic_command_line(const command_line&& other) = delete;
> basic_command_line & operator=(const command_line&& other) = delete;
> void print() const;
> ~basic_command_line();
> private:
> std::vector<std::string> args_;
> //std::vector<std::string<Allocater<char>,
> Allocator<std::string>> args_;

With the first template suggestion, this would be:

std::vector<std::basic_string<char, std::char_traits<char>, Allocator<char>
>, Allocator<std::basic_string<char, std::char_traits<char>, Allocator<char> > > > args_;

And with the second one:

std::vector<std::basic_string<char, std::char_traits<char>, AllocChar>,
AllocString> args_;

> };
>
> typedef basic_command_line command_line;
>
> }
>
> #endif

(Untested, I hope I got all those pointy brackets right)

Unfortunately, this is all rather clumsy.

Tobi

rob.d...@googlemail.com

unread,
Dec 10, 2012, 2:20:40 PM12/10/12
to

On Saturday, 8 December 2012 10:04:36 UTC, ken...@googlemail.com wrote:
> Hello, if I have a different allocator, can I use that allocator to
>
> allocate memory with vector or string as private member? How so?

std::allocator<T> provides a static 'rebind' mechanism such that you can at
least obtain a related allocator but for different types; like this:
typedef std::allocator< int > int_allocator;
typedef int_allocator::rebind< std::string >::other string_allocator;

In case of custom allocators this is also available as a unified interface
through std::allocator_traits (C++11 only):
template<typename T, typename Allocator = std::allocator<T>>
struct rebinds_allocator {
using string_allocator = typename
std::allocator_traits<Allocator>::template rebind_alloc<std::string>;
};


Tobi's technique of taking the allocator as a template template parameter
(instead of as a template type parameter) is a useful pattern I've used
occasionally for policy-based design where no equivalent rebind mechanism
exists.

HTH --rob
Reply all
Reply to author
Forward
0 new messages