【问题标题】:MSVC++ compiler error C2143MSVC++ 编译器错误 C2143
【发布时间】:2010-10-18 01:36:44
【问题描述】:

以下代码摘录导致了一个神秘的 MSVC++ 编译器错误:

template<class T> class Vec : public vector<T>{
  public:
    Vec() : vector<T>(){}
    Vec(int s) : vector<T>(s){}

    T& operator[](int i){return at(i);  }
    const T& operator[](int i)const{ return at(i);}
};

...

错误:

test.cpp(5) : error C2143: syntax error : missing ',' before '<'
  test.cpp(12) : see reference to class template instantiation 'Vec<T>' being compiled

我该如何解决这个问题?

---编辑---

一些上下文:

我正在尝试编译从C++ 编程语言复制和粘贴的代码。我什至还没有完全理解这段代码。然而,其目的是实现一个向量类型,当某些代码尝试访问向量范围之外的项目时会抛出异常,而不是仅仅返回不正确的值。

【问题讨论】:

  • 请显示 Vec 的实例化
  • 你的课毫无意义。默认情况下,MSVC 中的 operator[] 也执行边界检查,就像 at() 一样。所以你实际上并没有在类中添加任何新东西,只是引入了潜在的错误(参见 JaredPar 的回答)。

标签: c++ visual-c++ compiler-errors


【解决方案1】:

您为什么要尝试从向量继承?这会给你带来很多问题。其中最少的是该向量没有虚拟析构函数。这将导致在删除对您的类的多态引用时调用错误的析构函数,这将导致内存泄漏或一般的不良行为。

例如,下面的代码不会调用~Vec(),而是调用~vector()。

vector<int> *pVec = new Vec<int>();
delete pVec;  // Calls ~vector<T>();

您看到的实际编译错误是因为您使用模板语法进行基本构造函数调用。只需删除它,它应该可以编译

Vec() : vector() {}

【讨论】:

  • +1。你警告非多态删除是对的,但是OTOH,任何动态分配向量的代码无论如何都是可疑的。 (我能想到的动态分配某些东西的唯一原因是当你直到运行时才知道它的大小——但一个向量的大小无论如何在运行时可能会发生变化。)
  • 动态分配某些东西的主要原因是您直到运行时才知道有多少项,或者它们的实际类型是什么。
  • @Neil:一般来说好点,但在向量的特定情况下:(1)不知道有多少:使用向量向量比动态分配向量数组更安全; (2) 不知道实际类型:不知道你想要的向量的确切类型在我看来像是过度设计。
【解决方案2】:

试试

template<class T> class Vec : public vector<T>{
  public:
    Vec() : vector(){} // no <T>
    Vec(int s) : vector(s){} // same

    T& operator[](int i){return at(i);  }
    const T& operator[](int i)const{ return at(i);}
};

模板类的构造函数的名称中不包含模板签名。

顺便说一句,你的第二个构造函数应该是

Vec(typename vector<T>::size_type s) : vector(s){} // not necessarily int

最后,你真的不应该从向量派生,因为它有一个非虚拟的析构函数。不要试图通过指向向量的指针来删除 Vec。

【讨论】:

  • 其实第二个构造函数应该是Vec(size_type s)。它是向量中元素的数量,而不是要放入向量中的元素。
  • @Benoît:不一定。 std::vector 定义 size_type,它可能与 size_t 相同也可能不同。
【解决方案3】:

来自MSDN: Compiler Error C2143 (C++)

对标准 C++ 库中的类型进行了非限定调用:
// C2143g.cpp
// compile with: /EHsc /c
#include <vector>
static vector<char> bad;   // C2143
static std::vector<char> good;   // OK

这只是咬我。您只需修复对vector&lt;T&gt; 的引用,将它们替换为std::vector&lt;T&gt;

【讨论】: