<分区>
问题是为什么这段代码不能编译,特别是为什么我会得到一些奇怪的编译错误,比如
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;
}
为了提供更多上下文,我正在尝试重新实现一些数据结构作为练习,我现在正在努力研究“复合”数据结构(HashSet,一个过于简化的版本的 unordered_set
) 实现为 vector
带有 linked_list
的水桶在他们每个人中。
vector 和 list 实现都是我自己的,因此实现中的错误很可能是上坡路,这就是最小示例如此长的原因。我需要包括两个“模拟”类。
正如我所说,上面的代码无法编译,如果我运行 g++ file.cpp -std=c++11 给我
file.cpp:61:57: error: expected ‘;’ before ‘<’ token
即他在期待 using c_iterator = typename Container<T>::C_Iterator<Is_Const>;
成为using c_iterator = typename Container<T>::C_Iterator
相反。
很奇怪,如果我运行它确实会提示
error: ‘typename Container<int>::C_Iterator’ names ‘template<bool Is_Const> struct Container<int>::C_Iterator’, which is not a type
所以模板应该在那里!我的代码有什么问题?
编辑:我想到了尝试使用 clang++
进行编译的好主意它建议我将第 61 行修改为
using c_iterator = typename Container<T>::template C_Iterator<Is_Const>;
现在可以了;但是我不知道额外的是什么 ::template
正在做,所以问题是.. 为什么我必须那样做?什么是 ::template
提示编译器允许代码现在编译?