Good day!
I faced the following problem: I am writing a class of matrices, and I would like it to be possible to set both matrix dimensions fixed in compile-time and dynamically changeable. The whole project should be in the spirit of boost or stl, so I wrote two classes of arrays that are used in the matrix class to store values. Here is their shortened announcement:
template< typename T, typename _Derived > struct _Vector_base // Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΊΠ»Π°ΡΡ Π²Π΅ΠΊΡΠΎΡΠΎΠ²: ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ Π΄Π»Ρ typedef { public: typedef _Vector_base<T, _Derived> base_type; typedef T value_type; typedef size_t size_type; typedef T* pointer; typedef const T* const_pointer; typedef pointer iterator; typedef const_pointer const_iterator; }; template< typename _Scalar > class vector : // ΠΊΠ»Π°ΡΡ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ Π²Π΅ΠΊΡΠΎΡΠ° _Vector_base<_Scalar, vector<_Scalar> > { // ... }; template< typename _Scalar, size_t _Size > class fixed_vector : // ΠΊΠ»Π°ΡΡ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π²Π΅ΠΊΡΠΎΡΠ° _Vector_base<_Scalar, fixed_vector<_Scalar, _Size> > { // ... }; template< typename _Scalar, typename _Container > class _Matrix // ΠΠ°Π·ΠΎΠ²ΡΠΉ ΠΊΠ»Π°ΡΡ Π²ΡΠ΅Ρ
ΠΌΠ°ΡΡΠΈΡ - typedef'Ρ ΠΈ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ { public: typedef _Matrix<_Scalar, _Container> base_type; typedef size_t size_type; typedef _Scalar value_type; typedef _Scalar* pointer; typedef _Scalar& reference; typedef const _Scalar* const_pointer; typedef const _Scalar& const_reference; typedef _Container container_type; _Matrix() : nrows(0), ncols(0) { } _Matrix(size_t n, size_t m) : nrows(n), ncols(m){ } inline size_type size() const { return (nrows * ncols); } inline size_type rows() const { return nrows; } inline size_type columns() const { return ncols; } inline bool empty() const { return ((nrows == 0) && (ncols == 0)); } protected: size_t nrows, ncols; _Container m; }; // end class _Matrix // ΠΊΠ»Π°ΡΡ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΡ
ΠΌΠ°ΡΡΠΈΡ (ΠΎΠ±ΡΠΈΠΉ ΡΠ»ΡΡΠ°ΠΉ) template< typename _Scalar, typename _Container = vector<_Scalar> > class matrix : public _Matrix<_Scalar, _Container> { public: matrix(size_t _Rows, size_t _Cols) : _Matrix(_Rows, _Cols) { } }; // ΡΠ°ΡΡΠΈΡΠ½Π°Ρ ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΊΠ»Π°ΡΡΠ° ΠΌΠ°ΡΡΠΈΡ Π΄Π»Ρ ΠΌΠ°ΡΡΠΈΡ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ°Π·ΠΌΠ΅ΡΠ° template< typename _Scalar, size_t _Rows, size_t _Cols > class matrix<_Scalar, fixed_vector<_Scalar, (_Rows * _Cols)> > : public _Matrix<_Scalar, fixed_vector<_Scalar, _Rows*_Cols> > { public: matrix() : _Matrix(_Rows, _Cols) { } }; I assumed that the use would be something like this:
int main(int argc, char * argv[]) { matrix<float> m(2, 2); // Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠ°Ρ ΠΌΠ°ΡΡΠΈΡΠ° matrix<float, 2, 2> x; // ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½Π°Ρ ΠΌΠ°ΡΡΠΈΡΠ° return 0; } However, the compiler (MS Visual Studio 2012) does not skip this:
ClCompile: main.cpp ..\main.cpp(62): error C2977: 'matrix' : too many template arguments ..\main.cpp(12): see declaration of 'matrix' ..\main.cpp(62): error C2133: 'x' : unknown size ..\main.cpp(62): error C2512: 'matrix' : no appropriate default constructor available Build FAILED. Actually the question is: is it possible to compile this or something contrary to the rules of C ++? And if so how to do it?
In principle, I could make a separate class for fixed matrices (for example, fixed_matrix<T, N> ), but it is still interesting to find out why this particular option does not work.