Информация об изменениях

Сообщение Re[3]: Можно ли и как канонично получить из итератора тип эл от 17.04.2025 23:04

Изменено 17.04.2025 23:18 Marty

Re[3]: Можно ли и как канонично получить из итератора тип эл
Здравствуйте, rg45, Вы писали:

M>>Никак не понимает, что я хочу. Как объяснить?


R>Ну так конечно, у тебя же последняя перегрузка невыводимая в принципе.


Ну я не настоящий сварщик


R>Ты прикинь, одновременно 100500 классов контейнеров могут иметь одинаковые типы итераторов и какой тип контейнера должен при этом вывестись?


А мне на тип контейнера наплевать, мне интересен тип, который получается при разыменовании ContainerType::iterator, при этом, если мне дали итератор не последовательногопроизвольного доступа, и я начал с ним работать — эта проблема меня не волнует, я не хочу парится с детектом такой ситуации.


R>На С++20 эта задача решается легко и изящно:


А на С++17?

Мне бы хотелось привести к указателю на char
— итератор любого стандартного контейнера с произвольным доступом, который содержит элементы типа char или интегрального тип такого же размера (по размеру — желательно, но не обязательно)
— сам char* или const char*
— свой итератор, который при разыменовании возвращает не ссылку на элемент по хранимому в нем char-указателю, а произвольное значение by value. У последнего типа итератора есть метод rawPtr


R>Можно сделать аналог и на SFINAE, но там чуть больше пыли глотать придётся.


Ну, намекни, куда копать, мне пока не понятно. Сделал совсем тупо для базовых кейсов — тоже не прокатило:

//----------------------------------------------------------------------------
template<typename CharType>
const char* rawConstCharPtrFromIterator(marty::utf::UtfInputIterator<CharType> it)
{
    return (const char*)it.rawPtr();
}

template<typename CharType>
const char* rawConstCharPtrFromIterator(typename std::basic_string<CharType>::iterator it)
{
    return (const char*)(&*it);
}

template<typename CharType>
const char* rawConstCharPtrFromIterator(typename std::basic_string<CharType>::const_iterator it)
{
    return (const char*)(&*it);
}
Re[3]: Можно ли и как канонично получить из итератора тип эл
Здравствуйте, rg45, Вы писали:

M>>Никак не понимает, что я хочу. Как объяснить?


R>Ну так конечно, у тебя же последняя перегрузка невыводимая в принципе.


Ну я не настоящий сварщик


R>Ты прикинь, одновременно 100500 классов контейнеров могут иметь одинаковые типы итераторов и какой тип контейнера должен при этом вывестись?


А мне на тип контейнера наплевать, мне интересен тип, который получается при разыменовании ContainerType::iterator, при этом, если мне дали итератор не последовательногопроизвольного доступа, и я начал с ним работать — эта проблема меня не волнует, я не хочу парится с детектом такой ситуации.

Хотя, был наверное не прав в формулировках. Я исхожу из той концепции, что итератор либо указывает на реальную память, и при разыменовании возвращает что-то, с чем можно сделать &*it, и какие-то другие типы итераторов, которые надо отдельно обрабатывать.

Тут подумалось, можно попробовать:
— является ли итератор простым указателем
— можно ли сделать &*it
— огород для других типов итераторов

но не уверен, что компилятор меня поймёт, да и как реализовать, пока не очень понимаю.

Наверное, надо копнуть на тему enable_if c decltype/decay по типу *it


R>На С++20 эта задача решается легко и изящно:


А на С++17?

Мне бы хотелось привести к указателю на char
— итератор любого стандартного контейнера с произвольным доступом, который содержит элементы типа char или интегрального тип такого же размера (по размеру — желательно, но не обязательно)
— сам char* или const char*
— свой итератор, который при разыменовании возвращает не ссылку на элемент по хранимому в нем char-указателю, а произвольное значение by value. У последнего типа итератора есть метод rawPtr


R>Можно сделать аналог и на SFINAE, но там чуть больше пыли глотать придётся.


Ну, намекни, куда копать, мне пока не понятно. Сделал совсем тупо для базовых кейсов — тоже не прокатило:

//----------------------------------------------------------------------------
template<typename CharType>
const char* rawConstCharPtrFromIterator(marty::utf::UtfInputIterator<CharType> it)
{
    return (const char*)it.rawPtr();
}

template<typename CharType>
const char* rawConstCharPtrFromIterator(typename std::basic_string<CharType>::iterator it)
{
    return (const char*)(&*it);
}

template<typename CharType>
const char* rawConstCharPtrFromIterator(typename std::basic_string<CharType>::const_iterator it)
{
    return (const char*)(&*it);
}