void for_each(Mat1 mat1, Mat2 mat2, Mat3 mat3, Mat4 mat4, Func func) { assert(Mat1::FOR_EACH_ABLE == Mat1::FOR_EACH_ABLE); assert(Mat2::FOR_EACH_ABLE == Mat2::FOR_EACH_ABLE); assert(Mat3::FOR_EACH_ABLE == Mat3::FOR_EACH_ABLE); assert(Mat4::FOR_EACH_ABLE == Mat4::FOR_EACH_ABLE); assert(mat1.rows() == mat2.rows() && mat1.cols() == mat2.cols()); assert(mat1.rows() == mat3.rows() && mat1.cols() == mat3.cols()); assert(mat1.rows() == mat4.rows() && mat1.cols() == mat4.cols()); for (int y = 0; y < mat1.rows(); ++y) { auto p1 = mat1[y]; auto p2 = mat2[y]; auto p3 = mat3[y]; auto p4 = mat4[y]; for (int x = 0; x < mat1.cols(); ++x) { func(*p1, *p2, *p3, *p4); p1 += 1, p2 += 1, p3 += 1, p4 += 1; } } }