For a start, it is better to use brigand for c ++ 11 or boost :: hana for c ++ 14, it is easier, more convenient and faster to compile.
If you need boost :: mpl, you need to do something like this:
#include <boost/mpl/vector_c.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/range_c.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/copy.hpp> #include <boost/mpl/at.hpp> template <class T> struct check_type; // Для проверки значения типа во время компиляции // Исходный заполнитель template<int I, int J, int N> struct magic_number_t : boost::mpl::int_<1 + ((I - J + (N - 1) / 2) % N) * N + ((I + J + (N + 1) / 2) % N)> { }; // Заполнитель строки (для строки известно I и N, переменная - J; I,J,N передаются как mpl::int_ template<class I, class N> struct element_in_row_mfn{ template<class J> struct apply: magic_number_t<I::value, J::value, N::value> {}; }; // Генерирует I-ю строку, N - постоянная template<std::size_t N> struct make_row_mfn { template<class I> struct apply{ typedef boost::mpl::range_c<int, 0 , N> col_range_; // результат метафункции typedef typename boost::mpl::transform<col_range_, // Источник 0, 1, ...N-1 element_in_row_mfn<I, boost::mpl::int_<N> >, // Метафункция boost::mpl::back_inserter<boost::mpl::vector<> > // Потребитель >::type type; }; }; enum {N = 3}; // input // Применение метофункции make_columns<N> для каждого заголовка строки генерирует столбец typedef typename boost::mpl::transform< boost::mpl::range_c <int, 0, N>, // Источник 0, 1, ...N-1 make_row_mfn<N>, // Метафункция boost::mpl::back_inserter<boost::mpl::vector<> > // Потребитель >::type matrix; // Magic matrix // это уже с++11 template <int i, class row> using row_at = typename boost::mpl::at<row, boost::mpl::int_<i>>::type; template <int i, int j, class Matrix> using matrix_at = row_at<j, row_at<i, Matrix>>; int main() { // Вывод результата в виде сообщений об ошибке. Можно воспользоваться stsatic_assert вместо вывода check_type<matrix_at<0, 0, matrix > > v00; check_type<matrix_at<0, 1, matrix > > v01; check_type<matrix_at<0, 2, matrix > > v02; check_type<matrix_at<1, 0, matrix > > v10; check_type<matrix_at<1, 1, matrix > > v11; check_type<matrix_at<1, 2, matrix > > v12; check_type<matrix_at<2, 0, matrix > > v20; check_type<matrix_at<2, 1, matrix > > v21; check_type<matrix_at<2, 2, matrix > > v22; return 0; }
Result:
main.cpp: In function 'int main()': main.cpp:55:43: error: aggregate 'check_type<mpl_::int_<6> > v00' has incomplete type and cannot be defined check_type<matrix_at<0, 0, matrix > > v00; ^~~ main.cpp:56:43: error: aggregate 'check_type<mpl_::int_<1> > v01' has incomplete type and cannot be defined check_type<matrix_at<0, 1, matrix > > v01; ^~~ main.cpp:57:43: error: aggregate 'check_type<mpl_::int_<-1> > v02' has incomplete type and cannot be defined check_type<matrix_at<0, 2, matrix > > v02; ^~~ main.cpp:59:43: error: aggregate 'check_type<mpl_::int_<7> > v10' has incomplete type and cannot be defined check_type<matrix_at<1, 0, matrix > > v10; ^~~ main.cpp:60:43: error: aggregate 'check_type<mpl_::int_<5> > v11' has incomplete type and cannot be defined check_type<matrix_at<1, 1, matrix > > v11; ^~~ main.cpp:61:43: error: aggregate 'check_type<mpl_::int_<3> > v12' has incomplete type and cannot be defined check_type<matrix_at<1, 2, matrix > > v12; ^~~ main.cpp:63:43: error: aggregate 'check_type<mpl_::int_<2> > v20' has incomplete type and cannot be defined check_type<matrix_at<2, 0, matrix > > v20; ^~~ main.cpp:64:43: error: aggregate 'check_type<mpl_::int_<9> > v21' has incomplete type and cannot be defined check_type<matrix_at<2, 1, matrix > > v21; ^~~ main.cpp:65:43: error: aggregate 'check_type<mpl_::int_<4> > v22' has incomplete type and cannot be defined check_type<matrix_at<2, 2, matrix > > v22;