enable_if U является потомком интерфейса <T> - PullRequest
0 голосов
/ 06 июля 2018

До C ++ 14

В моем примере у меня есть begin() для пользовательского итератора. Пока у меня есть это

template<typename T>
inline auto
begin(ISomeIterator<T> &it)
  -> RangeForISomeIterator<ISomeIterator<T>>
{
  return it;
}

template<typename T>
inline auto
begin(ISomeConstIterator<T> &it)
  -> RangeForISomeConstIterator<ISomeConstIterator<T>>
{
  return it;
}

Я хотел бы изменить это, чтобы использовать статический тип контекста вызывающей стороны. Давайте назовем фактические реализации TheIterator и TheConstIterator, которые являются потомками ISomeIterator<Apple> и ISomeConstIterator<Apple> соответственно. Я хотел бы создать RangeForISomeIterator<TheIterator>, когда вызывается begin(theIt) и RangeForISomeConstIterator<TheConstIterator>, когда вызывается begin(theConstIt).

begin(U &it)
// where U is a descendant of ISomeIterator<T>

begin(U &it)
// where U is a descendant of ISomeConstIterator<T>

1 Ответ

0 голосов
/ 06 июля 2018

Просто объявите правильных Iterator членов и отправьте на std::is_const<std::iterator_traits<IT>::value_type>.

namespace detail
{
    template<typename IT>
    inline auto begin(IT&& it, std::false_type)
      -> RangeForISomeIterator<IT>
    {
      return std::forward<IT>(it);
    }

    template<typename IT>
    inline auto begin(IT&& it, std::true_type)
      -> RangeForISomeConstIterator<IT>
    {
      return std::forward<IT>(it);
    }
}

template<typename IT>
inline auto begin(IT&& it)
  -> decltype(detail::begin(std::forward<IT>(it), std::is_const<typename std::iterator_traits<It>::value_type>{}))
{
  return detail::begin(std::forward<IT>(it), std::is_const<typename std::iterator_traits<It>::value_type>{});
}

PS Почему у вас есть итераторы (публично), спускающиеся с что-нибудь ?

...