С++: эффективный swap() при использовании настраиваемого распределителя
Кажется, это месяц шаблонов С++ для меня...
У меня есть SecureString. SecureString выглядит так же, как std::string, за исключением того, что использует собственный распределитель, который обнуляет при уничтожении:
class SecureString
{
public:
typedef std::basic_string< char, std::char_traits<char>, zallocator<char> > SecureStringBase;
typedef zallocator<char>::size_type size_type;
static const size_type npos = static_cast<size_type>(-1);
....
private:
SecureStringBase m_base;
};
Полный код для SecureString можно найти по адресу http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/SecureString.h; и код для распределителя можно найти в http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/zAllocator.h.
В настоящее время мы определили swap
, который принимает std::string в качестве аргумента:
void SecureString::swap(std::string& str)
{
SecureStringBase temp(str.data(), str.size());
m_base.swap(temp);
str = std::string(temp.data(), temp.size());
}
Я чувствую, что у меня нет возможности в swap
, потому что базовые типы отличаются только распределителями. Может ли кто-нибудь увидеть способ избежать временного? Можно ли использовать rebind
для ускорения этого запуска?
EDIT: SecureString::swap(std::string& str)
теперь исчез. Ссылка на функцию в этом потоке осталась на месте для потомков.
Джефф
Ответы
Ответ 1
К сожалению... нет.
Это не для rebind
. rebind
используется потому, что распределитель предназначен для размещения объектов одного типа и только одного типа (std::allocator<T>
) в STL.
Однако есть трюк. Например, когда вы создаете экземпляр std::list<T, std::allocator<T>>
, тогда allocator
не нужно выделять T
s, он должен выделять некоторую внутреннюю структуру, а не как __list_node<T>
, и именно тогда, когда rebind
используется, это создает новый распределитель, родственный экземпляр предиката (они отличаются только параметром шаблона и, вероятно, используют один и тот же пул памяти под обложками).
В вашем случае, однако, ваш распределитель и распределитель std::string
отличаются друг от друга, и поэтому они не могут обмениваться памятью. Поэтому вам нужно сделать копию.
Вы можете оптимизировать операцию void swap(SecureString&, SecureString&)
, но не эту.
Один вопрос: почему бы не typedef std::string<char, SecureAllocator<char>> SecureString;
?