Ответ 1
Есть способ справиться с этим, но вам нужно немного подумать о коробке. Вам нужен промежуточный тип, который неявно можно построить как из std::string
, так и из вашей строки распределителя.
В настоящее время перед комитетом С++ есть предложение для такого вещания. Он основан на уже существующей версии Apache с лицензией Google, которая уже существует. Он назывался basic_string_ref
; это класс шаблона, который в основном является указателем на первый символ в строке и размером, представляющим длину строки. Это не настоящий контейнер в том смысле, что он не управляет памятью.
Это именно то, что вам нужно.
basic_string_ref
для определенного типа символа и типа признаков неявно можно построить из std::basic_string
независимо от распределителя.
Все операторы сравнения могут быть определены в терминах basic_string_ref
. Так как он неявно конструктивен из std::basic_string
(и фактически свободен для построения), он будет работать прозрачно для сравнения между выделенными друг другу строками.
Выполнение задания довольно сложнее, но выполнимо. Для этого требуется серия преобразований:
a = pstring{basic_string_ref{y}};
Не самый красивый код, конечно. Мы бы предпочли просто изменить конструктор копирования и оператор присваивания std::basic_string
как агностик-распределитель. Но так как это не выполнимо, это действительно самое лучшее. Вы можете даже обернуть его в функцию шаблона:
template<typename DestAllocator, typename SourceAllocator, typename charT, typename traits>
std::basic_string<charT, traits, DestAllocator> conv_str(const std::basic_string<charT, traits, SourceAllocator> &input)
{
return std::basic_string<charT, traits, DestAllocator>{basic_string_ref<charT, traits>{y}};
}
Конечно, если вы можете это сделать, вы можете просто сделать это:
template<typename DestAllocator, typename SourceAllocator, typename charT, typename traits>
std::basic_string<charT, traits, DestAllocator> conv_str(const std::basic_string<charT, traits, SourceAllocator> &input)
{
return std::basic_string<charT, traits, DestAllocator>{y.begin(), y.end()};
}
Было бы здорово, если бы это было всего лишь частью std::basic_string
, так что вам не нужны обходные пути. Но это не так.