Итератор шаблона внутри класса шаблона, clang не может определить параметр шаблона

У меня есть шаблонный класс с вложенным шаблоном пользовательских итераторов (специализируется на константных / неконстантных итераторах), например:

template <typename T>
struct A
{
    template <typename U>
    struct AIterator
    {
        //...
    };

    typename AIterator<T*> iterator;
    typename AIterator<const T*> const_iterator;
};

template <typename T>
bool operator==(const typename A<T>::iterator& lhs,
                const typename A<T>::iterator& rhs,)
{
    //...
}

template <typename T>
bool operator!=(const typename A<T>::iterator& lhs,
                const typename A<T>::iterator& rhs,)
{
    //...
}

//idem for const_iterator...

Но clang не может определить параметр шаблона:

snake_test.cpp:17:68: error: invalid operands to binary expression ('wavelet::Snake<float>::const_iterator' (aka 'Iterator<const float *>') and 'const_iterator' (aka 'Iterator<const float *>'))
        for (wavelet::Snake<float>::const_iterator it = snake.begin(); it != snake.end(); it++)
                                                                       ~~ ^  ~~~~~~~~~~~
./snake.hpp:150:6: note: candidate template ignored: couldn't infer template argument 'T'
bool operator!=(const typename Snake<T>::iterator& lhs,
     ^
./snake.hpp:164:6: note: candidate template ignored: couldn't infer template argument 'T'
bool operator!=(const typename Snake<T>::const_iterator& lhs,
     ^
1 error generated.

Что я делаю неправильно? Как правильно реализовать пользовательские итераторы для шаблонных классов?

1 ответ

Решение

Возможно, самое простое и чистое решение - использовать функции, не являющиеся членами-друзьями, определенные внутри тела класса:

template <typename T>
struct A
{
    template <typename U>
    struct AIterator
    {
        friend bool operator==(AIterator const& lhs, AIterator const& rhs)
        { /* implement here */ }
    };

    typename AIterator<T*> iterator;
    typename AIterator<const T*> const_iterator;
};

Это создаст функцию, не являющуюся членом для каждой специализации AIterator, Насколько я знаю, вы не можете предоставить определение для этой функции, не являющейся членом, - это не шаблон функции, а подходящая функция для каждой специализации. Таким образом, вы можете определить только фиксированный набор специализаций в глобальном пространстве имен.

Другие вопросы по тегам