Reputation: 1258
I'm using Visual Studio Professional 2013. I have a rather odd problem. Normally people post about getting errors - I'm here posting about NOT getting errors.
I have written a custom Matrix class (for homework). I have overriden the assignment operator as follows:
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;
}
I recently changed the newMatrixArray() method to accept a bool parameter:
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];
}
}
}
However, Visual Studio still compiles successfully... UNLESS
#include "Matrix.h"
int main() {
Matrix<int> matrix;
Matrix<int> otherMatrix;
otherMatrix = matrix;
return 0;
}
I write some code that uses the overloaded assignment operator. This is worrying me because now I don't know what else could be broken and Visual Studio isn't telling me!
What's going on with this?
More information:
As you can see, I am using templates. All the Matrix code is in the Matrix.h file - declaration followed by definition. This is required when using templates. The Matrix class is the only class I have right now in my project besides the main.cpp file. I have checked and made sure the declaration and definition match.
Credit: Praetorian
Edit: (SOLUTION)
You can use:
template class NameOfClass<NameOfType>;
to compile template classes against a certain type.
You can also use:
template ReturnType NameOfFunction(Args ... );
to compile outside-of-class methods with template arguments.
These should be placed in the global scope.
Upvotes: 3
Views: 191
Reputation: 120089
The standard basically requires to perform most checks at declaration time. Only checks that cannot be so performed are postponed until instantiation time. The latter checks are those that involve dependent names. See here for a detailed explanation.
Since newMatrixArray
is dependent, it will not be checked until instantiation time. And if a member function is never used, it is not instantiated.
The reason for this rule is the fact that the meaning of a dependent name is not fully known until template parameters are known.
The problem with (at least some versions of) MSVC is that even non-dependent names are not checked until instantiation time. You can try to compile this program to check if your compiler is affected. If it compiles, there is a bug.
Upvotes: 0
Reputation: 206737
You said:
This is worrying me because now I don't know what else could be broken and Visual Studio isn't telling me!
What's going on with this?
There is nothing wrong with what the compiler is doing. If a member function of a class template is not used, the function doesn't get instantiated. Some errors will be reported regardless of whether the function is instantiated or not, like mismatched parentheses, but other errors, like the one you mentioned won't be reported unless the function is instantiated.
Upvotes: 1
Reputation: 7687
If something in a template isn't used, it won't be (fully) parsed either, and don't give out errors.
It pretty much have to be this way, and this is not a VS bug, its conformant behaviour.
Consider:
template<typename T>
class X
{
public:
void work_always(const T&) {}
void requires_copyable(T) {}
};
If you instance this on a type that is not copyable, it should still work, as long as you
only use work_always
The standard library even uses this, for example vectors resize, that
require T to be
default constructible, but vector can still be used on types that aren't,
as long as you
dont call any methods requiring it.
This, of course, make template testing a bit hard, you have to make sure to use everything.
Upvotes: 0