Murilo :P

C++, Computação, Programação, Web e afins :)

Static Template Matrix – uma abordagem diferente

with 5 comments

Static Template Matrix?

C++
De fato eu nunca vi esse nome em outro lugar, mas foi o nome que eu pensei que se aproxima mais da implementação que veremos nesse post.

Trata-se template de uma matriz (matrix) de duas dimensões de tamanho constante (static). Uma das diferenças dessa matriz é que ao invés de se usar o convencional operator[] para acessar os elementos, nessa abordagem iremos utilizar o operator().

Motivações

Na realidade, não tem muito mais utilidades práticas do que matrizes normais. Pode ser que pode servir em algo para você. Então minha motivação é puramente de aprendizagem, principalmente da linguagem.

matrix.h

#ifndef _CLASS_MATRIX_H__
#define _CLASS_MATRIX_H__

/**
 * matrix.h
 * Defines a template type 'matrix' wich is a constant-sized 2-dimensioned
 * 	matrix and generic typed elements.
 *
 * author: Murilo Adriano Vasconcelos
 * website: https://murilo.wordpress.com
 */

/**
 * T = value type
 * R = number of rows
 * C = number of columns
 */
template <typename T, unsigned R, unsigned C>
class matrix
{
    //data matrix
    T data[R][C];

public:
    //type of the current matrix
    typedef matrix<T, R, C> type;
    typedef T            value_type;

    //quantity of rows
    const unsigned rows;
    //quantity of columns
    const unsigned columns;

    //default ctor
    matrix(): rows(R), columns(C) {};

    /*ctor wich initializes the matrix filled
      with 'value' elements */
    matrix(const T& value);

    //copy ctor: copies the matrix 'tocopy'
    matrix(const type& tocopy);

    /*gets and/or set the value of the element
      in the row 'i', column 'j' */
    T& operator()(unsigned i, unsigned j);

    /*gets the value of the element in the
      row 'i', column 'j' */
    const T& operator()(unsigned i, unsigned j) const;

    //copy operator
    type& operator=(const type& tocopy);
};

/* class functions definition */

template <typename T, unsigned R, unsigned C>
matrix<T, R, C>::matrix(const matrix& tocopy): rows(R), columns(C)
{
    for (unsigned i = 0; i < R; i++)
        for (unsigned j = 0; j < C; j++)
            data[i][j] = tocopy(i, j);
}

template <typename T, unsigned R, unsigned C>
matrix<T, R, C>::matrix(const T& value): rows(R), columns(C)
{
    for (unsigned i = 0; i < R; i++)
        for (unsigned j = 0; j < C; j++)
            data[i][j] = value;
}

template <typename T, unsigned R, unsigned C>
matrix<T, R, C>& matrix<T, R, C>::operator=(const matrix& tocopy)
{
    for (unsigned i = 0; i < R; i++)
        for (unsigned j = 0; j < C; j++)
            data[i][j] = tocopy(i, j);

    return *this;
}

template <typename T, unsigned R, unsigned C>
T& matrix<T, R, C>::operator()(unsigned i, unsigned j)
{
    return data[i][j];
}

template <typename T, unsigned R, unsigned C>
const T& matrix<T, R, C>::operator()(unsigned i, unsigned j) const
{
    return data[i][j];
}

#endif

main.cpp

#include "matrix.h" //our matrix
#include <iostream>  //cout'ing
#include <string>   //for strings

int main()
{
        //declares a 3x3 matrix filled with "nil"
        matrix<std::string, 5, 5> mat("nil");

        //modifies the value in the position (1, 1) to C++
        mat(1, 1) = "C++";

        //we can use the const atribbutes rows and columns
        //to check our limits
        for (unsigned i = 0; i < mat.rows; i++) {
                for (unsigned j = 0; j < mat.columns; j++) {
                        //getting, setting the value of matrix elements
                        //is the same way
                        std::cout << mat(i, j) << ' ';
                }

                std::cout << '\n';
        }

        std::cout << '\n';

        matrix<int, 3, 3> ones(1), identity;
        //copy
        identity = ones;

        //so silly
        for (unsigned i = 0; i < identity.rows; i++) {
                for (unsigned j = i; j < identity.columns; j++) {
                        if (i != j) {
                                identity(i, j) = identity(j, i) = 0;
                        }
                }
        }

        for (unsigned i = 0; i < identity.rows; i++) {
                for (unsigned j = 0; j < identity.columns; j++) {
                        std::cout << identity(i, j) << ' ';
                }

                std::cout << '\n';
        }

        return 0;
}

Como vocês puderam notar, a forma de acesso e modificação (get, set) dos elementos da matriz é da mesma forma. Outra coisa que podemos notar é que passamos o tipo e a quantidade de linhas e colunas direto no template. A quantidade de linha e colunas passada deve ser uma constante.

Bom, até mais.

obs.: Eu odeio profundamente o source highlight bugado do WordPress que converte todos os meus < e > e etc. para &lt; &gt;. Por isso os fontes acima não estão com hl.

Fixed!

Agora sim, até mais.

Advertisements

Written by Murilo Adriano

12 de October de 2009 at 21:08

5 Responses

Subscribe to comments with RSS.

  1. Eu odeio profundamente o source highlight bugado do WordPress que converte todos os meus e etc. para < >. Por isso os fontes acima não estão com hl.

    Pensei que era apenas eu! 🙂

    bcsanches

    13 de October de 2009 at 10:25

    • E o pior é que as vezes, não se sabe o porquê, funciona…
      E quando não tem que converter ele converte ¬¬

      Vai saber :/

      Murilo Adriano

      13 de October de 2009 at 13:18

  2. Achei extremamente interessante esse conteúdo, queria lhe pedir permissão para utilizar esse código com os devidos créditos. Como eu poderia entrar em contato?

    Mathaus Mendel

    1 de September de 2010 at 17:11

    • Olá Mathaus!
      Pode utilizar sim do jeito que quiser 🙂
      Meu email é muriloufg .arroba. gmail .ponto. com

      Abraço!

      Murilo Adriano

      1 de September de 2010 at 17:37

  3. Ah, agora dei uma editada no conteúdo e está legal agora!
    Vai entender esse highlighter do WP…

    Murilo Adriano

    1 de September de 2010 at 17:38


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: