我正在使用Visual Studio Professional 2013.我有一个相当奇怪的问题。通常人们发布有关收到错误的帖子 - 我在这里发布的关于不会收到错误的帖子。
我写了一个自定义的Matrix类(用于家庭作业)。 我已按如下方式覆盖赋值运算符:
template<typename T>
Matrix<T>& Matrix<T>::operator=(const Matrix<T> &other) {
if (this != &other) {
if (this->mRows != other.mRows || this->nColumns != other.nColumns) {
deleteMatrixArray();
this->mRows = other.mRows;
this->nColumns = other.nColumns;
newMatrixArray();
} // else reuse the existing array
// copy contents
for (unsigned int i = 0; i < this->mRows; i++) {
for (unsigned int j = 0; j < this->nColumns; j++) {
this->matrix[i][j] = other.matrix[i][j];
}
}
}
return *this;
}
我最近更改了newMatrixArray()方法以接受bool参数:
template<typename T>
void Matrix<T>::newMatrixArray(bool init) {
this->matrix = new T*[this->mRows];
for (unsigned int i = 0; i < this->mRows; i++) {
if (init) {
this->matrix[i] = new T[this->nColumns]();
} else {
this->matrix[i] = new T[this->nColumns];
}
}
}
但是,Visual Studio仍然可以成功编译......除非
#include "Matrix.h"
int main() {
Matrix<int> matrix;
Matrix<int> otherMatrix;
otherMatrix = matrix;
return 0;
}
我编写了一些使用重载赋值运算符的代码。 这让我很担心,因为现在我不知道还有什么可以被打破,Visual Studio也没有告诉我!
这是怎么回事?
更多信息:
如您所见,我正在使用模板。所有Matrix代码都在Matrix.h文件中 - 声明后跟定义。使用模板时需要这样做。除了main.cpp文件之外,Matrix类是我项目中现在唯一的类。我检查并确保声明和定义匹配。
信用:Praetorian
编辑:(解决方案)
您可以使用:
template class NameOfClass<NameOfType>;
针对特定类型编译模板类。
您也可以使用:
template ReturnType NameOfFunction(Args ... );
使用模板参数编译类外的方法。
这些应放在全球范围内。
答案 0 :(得分:1)
你说:
这令我担心,因为现在我不知道还有什么可以被打破,Visual Studio也没有告诉我!
这是怎么回事?
编译器正在做什么没有错。如果未使用类模板的成员函数,则该函数不会被实例化。无论函数是否被实例化,都会报告一些错误,例如不匹配的括号,但是除非函数被实例化,否则会报告其他错误,例如您提到的错误。
答案 1 :(得分:0)
如果未使用模板中的某些内容,则不会(完全)解析它,也不会发出错误。
它几乎必须是这样的,这不是一个VS错误,它的符合行为。
考虑:
template<typename T>
class X
{
public:
void work_always(const T&) {}
void requires_copyable(T) {}
};
如果你在一个不可复制的类型上实例化它,它应该仍然可以工作,只要你
仅使用work_always
标准库甚至使用它,例如vector resize,即
要求T为
默认可构造,但vector仍可用于不是的类型,
只要你
不要求任何需要它的方法。
当然,这使得模板测试有点困难,你必须确保使用所有内容。
答案 2 :(得分:0)
标准基本上要求在申报时执行大多数检查。只有那些不能执行的检查才会推迟到实例化时间。后面的检查涉及依赖名称。有关详细说明,请参阅here。
由于newMatrixArray
是依赖的,因此在实例化时间之前不会检查它。如果从未使用过成员函数,则不会实例化它。
此规则的原因是,在知道模板参数之前,尚未完全了解从属名称的含义。
(至少某些版本的)MSVC的问题是在实例化时间之前甚至不检查非依赖名称。您可以尝试编译this program以检查编译器是否受到影响。如果它编译,则存在错误。