I\'m searching a way to check function arguments in compile-time if it\'s possible to do for compiler.
To be more specific: assume that we have some class Matrix.
The way that linear algebra packages tend to do this is to use templates for fixed size matrices, as in:
template<int x, int y> class Matrix { ... }
and an extra class for matrices that can change size at runtime
class DynamicMatrix {...}
You still have to rely on the programmer actually using the first option when they want fixed size matrices, but the template version makes it easy to generate a compiler error when x
or y
are zero.
Run-time:
Matrix(int width, int height):
x_size{width},
y_size{height}
{
assert(x_size>0);
assert(y_size>0);
}
Compile-time (Actually you couldn't do it with function arguments. You can use template ways):
template <size_t WIDTH, size_t HEIGHT>
class Matrix
{
const size_t x_size = WIDTH;
const size_t y_size = HEIGHT;
static_assert(WIDTH > 0, "Width must > 0");
static_assert(HEIGHT > 0, "Height must > 0");
};
To get a compile time error you would need a template:
template <int width, int height>
class MatrixTemplate : public Matrix
{
static_assert(0 < width, "Invalid Width");
static_assert(0 < height, "Invalid Height");
public:
MatrixTemplate()
: Matrix(width, height)
{}
};
(Btw.: I suggest unsigned types for indices)
If you do not have static_assert (here I switch to unsigned):
template <unsigned width, unsigned height>
class MatrixTemplate : public Matrix
{
public:
MatrixTemplate()
: Matrix(width, height)
{}
};
template <> class MatrixTemplate<0, 0> {};
template <unsigned height> class MatrixTemplate<0, height> {};
template <unsigned width> class MatrixTemplate<width, 0> {};
There is no support for empty matrices (MatrixTemplate<0, 0>), here. But it should be an easy task to adjust the static_asserts or class MatrixTemplate<0. 0>.
You may add a method like this:
template <int WIDTH, int HEIGHT>
Matrix CreateMatrix()
{
static_assert(WIDTH > 0, "WIDTH > 0 failed");
static_assert(HEIGHT > 0, "HEIGHT > 0 failed");
return Matrix(WIDTH, HEIGHT);
}
int main() {
Matrix m(0, 2); // no static check
Matrix m2 = CreateMatrix<0,2>(); // static check
return 0;
}