errors porting C++ templates from GCC to Visual C++
以下汇编在GCC中:
cvec.hpp公司:
1 2 3 4 5 | template <class T> class cvec : public deque<T> { class deque<T>::iterator Find(T); }; |
cvec.cpp公司:
1 2 3 4 5 | template <class T> class deque<T>::iterator cvec<T>::Find(T element) { } |
号
在Visual C++中,获取:
错误C2242"typedef名称不能跟在类/结构/联合之后。
我将头文件中的"class"更改为"typename",但接收错误c3860-模板参数列表必须按照模板参数列表中使用的顺序列出参数。这种情况下只有一个参数t,除非编译器对find(t元素)感到困惑?
在标题中这意味着什么:
1 | class deque<T>::iterator Find(T); |
您没有声明类。这里的
在.cpp文件中也是如此:
1 2 | template <class T> typename deque<T>::iterator cvec<T>::Find(T element) |
是正确的,
除此之外,看起来你真正想做的是一个可怕的想法。
标准库容器也不设计为派生自。它们没有虚拟析构函数。
你所取得的一切(除了编译错误)是,你最终会遇到一个笨重、效率较低的容器类,它会混淆其他C++程序员,因为它不使用惯用的接口。
这真的应该是一个评论,但我要把它作为一个答案,这样我就可以将其格式化以便于阅读。
@JALF和@dvl——正如@dvl上面所说的,所有的std容器都没有虚拟的析构函数。为什么这很重要?
假设您从std::deque派生了一个类"x"。
1 2 3 4 | class X : public std::deque<int> { // whatever ... }; |
现在假设您有一个"x"对象,由一个基指针指向。
1 | std::deque<int> *p = new X; |
然后删除它
1 | delete p; |
不会调用派生类X的析构函数,这可能会导致许多问题。
你的选择:1。不要从标准容器派生。使它们成为数据成员并编写包装器以公开功能。2。只有当派生类没有析构函数,也没有带有析构函数的数据成员时,才从std容器派生。三。如果您从一个标准容器派生,那么永远不要用基指针引用它。
在创建类之后,有时很难知道该类将来可能如何使用。因此,许多开发人员严格遵循选项"1"。就我个人而言,我允许从一个性病容器衍生,只要它是充分记录和小心使用。
这在2010年对我有效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <deque> template <class T> class cvec : public std::deque<T> { public: typedef typename std::deque<T>::iterator iterator; iterator Find(T element); }; template <class T> typename cvec<T>::iterator cvec<T>::Find(T element) { return std::deque<T>::iterator(); } using namespace std; int main() { cvec<int> c; c.Find(1); return 0; } |