ctype и строки и контейнеры - PullRequest
2 голосов
/ 19 июля 2010

Есть ли причина, по которой функции фасета ctype (is, scan_is, scan_not поддерживают только простой указатель на символ, а не контейнеры на основе итераторов, такие как std :: string или даже std :: vector ..тогда можно было бы написать:

const ctype<char>& myctype = use_facet<std::ctype<char> >(locale(""));
string foo_str = "hi there here is a number: 748574 and text again";
vector<char> foo(foo_str.begin(),foo_str.end());

//then one could write

vector<char>::iterator num_begin_it = myctype.scan_is( ctype<char>::digit, foo.begin(), foo.end() );
vector<char> foo_num_1( foo, num_begin_it, myctype.scan_not(ctype<char>::digit, num_begin_it, foo.end() );

//instead of:
const char* num_begin_pc = myctype.scan_is(ctype<char>::digit, &foo[0], &foo[foo.size()-1]+1); // &foo[foo.size()-1]+1) instead of foo.end() is not quite readable.
vector<char> foo_num_2(num_begin_pc, myctype.scan_not(ctype<char>::digit, num_begin_pc, &foo[foo.size()-1]+1));

//appendix:
//STL/Boost solution, even more verbose:

function<bool(char)> is_digit_func =
    bind(
        mem_fn(static_cast<bool (ctype<char>::*)(ctype<char>::mask,char) const>(&ctype<char>::is)),
        &myctype,
        ctype<char>::digit,
        _1
    );
vector<char>::iterator num_begin_0x = find_if(foo.begin(), foo.end(),is_digit_func);
vector<char> foo_num_3(num_begin_0x,find_if(num_begin_0x, foo.end(),not1(is_digit_func)));

// all 3 foo_num_X will now contain "748574"

Было бы здорово, если бы у кого-то было понимание, почему комитет по стандартизации принимал эти проектные решения?

И есть ли лучший (менее подробный) способиспользовать функции ctype с контейнерами на основе итераторов?

Решение STL / Boost было бы неплохо, если бы в этом не было необходимости

Кроме того, я обнаружил, что алгоритма copy_if нетв стандартной библиотеке, но я уже причина этого .

1 Ответ

2 голосов
/ 19 июля 2010

Основная причина в том, что Стандартная библиотека не была разработана как единое целое, но включает несколько библиотек, которые были популярны в то время.которая послужила основой для стандартных библиотек Containers, Iterators и Algorithms.Библиотеки Strings и Localization были получены из других источников, в которых не использовались итераторы.Поскольку итераторы очень полезны, было сочтено, что стоит попытаться дооснастить их этими библиотеками, но не полностью менять интерфейсы библиотек для использования итераторов везде.&foo[0] + foo.size() быть более читабельным, чем &foo[foo.size()-1]+1.Вам также не нужно копировать строку в вектор, чтобы использовать scan_is и scan_not;что-то вроде этого должно сделать работу:

const char* str_begin = foo_str.c_str();
const char* str_end   = str_begin + foo_str.length();
const char* num_begin = myctype.scan_is(ctype<char>::digit, str_begin, str_end);
const char* num_end   = myctype.scan_not(ctype<char>::digit, num_begin, str_end);
std::string number(num_begin, num_end); // or `vector` if you really want
...