This question already has an answer here:
The question is why doesn't this code compile and specifically why do I get some weird compilation errors like
error: non-template ‘C_Iterator’ used as template
?
#include <type_traits> // fot std::enable_if
#include <iostream>
template <class T>
struct Container{
template <bool Is_Const>
struct C_Iterator{
using value_type = T;
using pointer = T*;
using reference = T&;
using difference_type = std::ptrdiff_t;
using iterator_category = std::random_access_iterator_tag;
T* p;
// args c-tors
C_Iterator(T *p_): p(p_) {}
// Copy
C_Iterator(const C_Iterator<Is_Const>& other) = default;
template<bool Was_Const, class = typename std::enable_if<Is_Const || !Was_Const>::type>
C_Iterator(const C_Iterator<Was_Const>& other) : p{other.p}{}
C_Iterator &operator=(const C_Iterator &other){
p = other.p;
return *this;
}
reference operator*() {return *p;}
// some other stuff here
};
using iterator = C_Iterator<false>;
using const_iterator = C_Iterator<true>;
Container(T v) { storage = new int[1]; storage[0]=v; }
~Container() { delete storage; }
inline iterator begin() { return iterator(storage);}
inline const_iterator begin() const { return const_iterator(storage);}
T* storage;
};
template <class T>
struct Iterable_Wrapper{
template <bool Is_Const>
struct W_Iterator{
using value_type = T;
using pointer = T*;
using reference = T&;
using iterator_category = std::forward_iterator_tag;
using c_iterator = typename Container<T>::C_Iterator<Is_Const>;
c_iterator it;
// args c-tors
W_Iterator( c_iterator it_ ): it(it_) {}
// Copy
W_Iterator(const W_Iterator<Is_Const>& other) = default;
template<bool Was_Const, class = typename std::enable_if<Is_Const || !Was_Const>::type>
W_Iterator(const W_Iterator<Was_Const>& other) : it{other.it}{}
W_Iterator &operator=(const W_Iterator &other){
it = other.it;
return *this;
}
reference operator*() {return *it;}
// some other stuff here
};
using iterator = W_Iterator<false>;
using const_iterator = W_Iterator<true>;
Iterable_Wrapper(T v) : wrapped_container(v) {}
~Iterable_Wrapper() {}
inline iterator begin() { return iterator(wrapped_container.begin());}
inline const_iterator begin() const { return const_iterator(wrapped_container.begin());}
Container<T> wrapped_container;
};
int main()
{
Container<int> c{5};
auto it { c.begin() };
std::cout << *it << std::endl;
const Container<int> c2{10};
auto it2 { c2.begin() };
std::cout << *it2 << std::endl;
Iterable_Wrapper<int> w{15};
auto it3 { w.begin() };
std::cout << *it3 << std::endl;
return 0;
}
To give a bit more context, I'm trying to get a re-implementation of a few data structures as an exercise and I'm now struggling at a "composite" data structure ( a HashSet, an over-simplified version of an unordered_set
) implemented as a vector
of buckets with a linked_list
in each of them. Both vector and list implementation are my own, so it's likely the fault in the implementation is uphill and that's why the minimal example is so long.. I needed to include both "mock" classes.
As I said, the above code cannot compile and if I run g++ file.cpp -std=c++11 gives me
file.cpp:61:57: error: expected ‘;’ before ‘<’ token
i.e. he's expecting using c_iterator = typename Container<T>::C_Iterator<Is_Const>;
to be using c_iterator = typename Container<T>::C_Iterator
instead.
Weird, and indeed if I run it complains that error: ‘typename Container<int>::C_Iterator’ names ‘template<bool Is_Const> struct Container<int>::C_Iterator’, which is not a type
so the template should be there! What's wrong with my code?
Aucun commentaire:
Enregistrer un commentaire