C++模板化类给出"错误:非模板 X 用作模板"

C++ templated classes gives `error: non-template X used as template`

本文关键字:quot 错误 C++      更新时间:2023-10-16

问题是为什么这段代码不能编译,特别是为什么我会收到一些奇怪的编译错误,比如

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。 向量和列表实现都是我自己的,所以实现中的错误很可能是上坡路,这就是为什么最小示例这么长的原因。我需要包括两个"模拟"类。

正如我所说,上面的代码无法编译,如果我运行 g++ 文件.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向编译器暗示什么,允许代码现在编译?

它应该是

using c_iterator = typename Container<T>::template C_Iterator<Is_Const>;