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

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

Изменено 17.04.2025 22:29 rg45

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

M>Попробовал по-разному, последнее такое:


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

M>//----------------------------------------------------------------------------
M>template<typename CharPointerType>
M>typename std::enable_if< std::is_pointer<CharPointerType>::value, const char* >::type
M>rawConstCharPtrFromIterator(CharPointerType pstr)
M>{
M>    return (const char*)pstr;
M>}

M>//----------------------------------------------------------------------------
M>template<typename ContainerType>
M>typename std::enable_if< has_const_iterator<ContainerType>::value, const char* >::type
M>rawConstCharPtrFromIterator(typename ContainerType::const_iterator it)
M>{
M>    return (const char*)(&*it);
M>}

M>



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


Ну так конечно, у тебя же последняя перегрузка невыводимая в принципе. Ты прикинь, одновременно 100500 классов контейнеров могут иметь одинаковые типы итераторов и какой тип контейнера должен при этом вывестись?

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

template <typename T>
concept Dereferenceable = requires(T t) {{&*t} -> std::convertible_to<const void*>;};

template <typename T>
concept Pointer = Dereferenceable<T> and std::convertible_to<const void*>;

const char* rawConstCharPtrFromIterator(auto&& t)
requires requires { (const char*)t.rawPtr(); }
{
   return (const char*)t.rawPtr();
}

const char* rawConstCharPtrFromIterator(Pointer auto&& t)
{
   return (const char*)t;
}

const char* rawConstCharPtrFromIterator(Dereferenceable auto&& t)
{
   return (const char*)(&*t);
}


Можно сделать аналог и на SFINAE, но там чуть больше пыли глотать придётся.
Re[2]: Можно ли и как канонично получить из итератора тип эл
Здравствуйте, Marty, Вы писали:

M>Попробовал по-разному, последнее такое:


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

M>//----------------------------------------------------------------------------
M>template<typename CharPointerType>
M>typename std::enable_if< std::is_pointer<CharPointerType>::value, const char* >::type
M>rawConstCharPtrFromIterator(CharPointerType pstr)
M>{
M>    return (const char*)pstr;
M>}

M>//----------------------------------------------------------------------------
M>template<typename ContainerType>
M>typename std::enable_if< has_const_iterator<ContainerType>::value, const char* >::type
M>rawConstCharPtrFromIterator(typename ContainerType::const_iterator it)
M>{
M>    return (const char*)(&*it);
M>}

M>



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


Ну так конечно, у тебя же последняя перегрузка невыводимая в принципе. Ты прикинь, одновременно 100500 классов контейнеров могут иметь одинаковые типы итераторов и какой тип контейнера должен при этом вывестись?

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

template <typename T>
concept Dereferenceable = requires(T t) {{&*t} -> std::convertible_to<const void*>;};

template <typename T>
concept Pointer = Dereferenceable<T> and std::convertible_to<T, const void*>;

const char* rawConstCharPtrFromIterator(auto&& t)
requires requires { (const char*)t.rawPtr(); }
{
   return (const char*)t.rawPtr();
}

const char* rawConstCharPtrFromIterator(Pointer auto&& t)
{
   return (const char*)t;
}

const char* rawConstCharPtrFromIterator(Dereferenceable auto&& t)
{
   return (const char*)(&*t);
}


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