Контейнер STL с итераторами для себя: set vs unordered_set - PullRequest
0 голосов
/ 14 октября 2018

Я хотел бы создать контейнер с данными, который включает в себя итератор самого контейнера.Упрощенный код ниже.Он работает для большинства контейнеров STL (vector, set и т. Д.), Но не компилируется для unordered_set с некоторыми загадочными ошибками компиляции в проверке требований к хешу.

#include <set>
#include <unordered_set>

template <class C, class T>
struct rebind {};

template <class T0, class T>
struct rebind<std::set<T0>, T> {
    using type = std::set<T>;
};

template <class T0, class T>
struct rebind<std::unordered_set<T0>, T> {
    using type = std::unordered_set<T>;
};

template <class C>
class wrapped_iterator;

template <class C>
using twisted_container = typename rebind<C, wrapped_iterator<C>>::type;

template <class C>
class wrapped_iterator : public twisted_container<C>::iterator {
    size_t key() const { return reinterpret_cast<std::uintptr_t>(std::addressof(**this)); }
    bool operator < (const wrapped_iterator& other) const { return key() < other.key(); }
    bool operator == (const wrapped_iterator& other) const { return key() == other.key(); }
};

namespace std {

template <class C>
struct hash<wrapped_iterator<C>> {
    size_t operator()(wrapped_iterator<C> it) const {
        return it.key();
    }
};

}

int main() {
    twisted_container<std::set<int>> a;
    twisted_container<std::unordered_set<int>> b;  // This doesn't compile!
    return 0;
}

Ошибка лягушки:

<source>:24:59: error: no type named 'iterator' in 'std::unordered_set<wrapped_iterator<std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int> > >, std::hash<wrapped_iterator<std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int> > > >, std::equal_to<wrapped_iterator<std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int> > > >, std::allocator<wrapped_iterator<std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int> > > > >'
    class wrapped_iterator : public twisted_container<C>::iterator {
                                    ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~

Ошибка gcc:

<source>:24:11: error: invalid use of incomplete type 'twisted_container<std::unordered_set<int> >' {aka 'class std::unordered_set<wrapped_iterator<std::unordered_set<int> >, std::hash<wrapped_iterator<std::unordered_set<int> > >, std::equal_to<wrapped_iterator<std::unordered_set<int> > >, std::allocator<wrapped_iterator<std::unordered_set<int> > > >'}
     class wrapped_iterator : public twisted_container<C>::iterator {
           ^~~~~~~~~~~~~~~~

Я пытаюсь сделать что-то незаконное?Есть ли способ исправить эту ошибку?Почему unordered_set особенный в этом случае?Это предполагаемое поведение или ошибка в реализации компиляторов?

...