Re[4]: Можно ли и как канонично получить из итератора тип эл
От: rg45 СССР  
Дата: 18.04.25 07:47
Оценка: 12 (1)
Здравствуйте, Marty, Вы писали:

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

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

Ну, как-то так. И обрати внимание, если ты хочешь, чтоб работал ADL, перегрузку rawConstCharPtrFromIterator для UtfInputIterator нужно внести в неймспейс marty::utf.

https://coliru.stacked-crooked.com/a/456031d81cb952ce

#include <cstdint>
#include <iostream>
#include <type_traits>

template<typename, typename = void>
struct IsDereferenceableToLvalue_ : std::false_type {};

template<typename T>
struct IsDereferenceableToLvalue_<T, std::void_t<decltype(&*std::declval<T>())>> : std::true_type {};

template<typename T>
inline constexpr bool IsDereferenceableToLvalue = IsDereferenceableToLvalue_<T>::value;

template<typename T>
inline constexpr bool IsPointer = std::is_pointer_v<std::decay_t<T>>;

namespace marty {
namespace utf {

template <typename CharType>
struct UtfInputIterator
{
   const CharType& operator*() const;
   const CharType* rawPtr() const {return reinterpret_cast<const CharType*>("marty::utf::UtfInputIterator"); };
};

template<typename CharType>
const char* rawConstCharPtrFromIterator(UtfInputIterator<CharType> it)
{
   return reinterpret_cast<const char*>(it.rawPtr());
}

} // namespace utf
} // namespace marty

template<typename CharPointerType>
const char* rawConstCharPtrFromIterator(CharPointerType* pstr)
{
   return reinterpret_cast<const char*>(pstr);
}

template <typename IteratorType, std::enable_if_t<
    IsDereferenceableToLvalue<IteratorType>
    and not IsPointer<IteratorType>
, int> = 0>
const char* rawConstCharPtrFromIterator(IteratorType it)
{
   return reinterpret_cast<const char*>(&*it);
}

int main()
{
   const char* const c = "const char*";
   std::string const s = "std::string";
   marty::utf::UtfInputIterator<uint32_t> const it{};

   std::cout << rawConstCharPtrFromIterator(c) << std::endl;
   std::cout << rawConstCharPtrFromIterator(s.begin()) << std::endl;
   std::cout << rawConstCharPtrFromIterator(it) << std::endl;
}
--
Справедливость выше закона. А человечность выше справедливости.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.