Как указать произвольный аргумент шаблона для параметра функции? - PullRequest
0 голосов
/ 17 апреля 2019

Я не был уверен, как сформулировать то, что я спрашиваю, так что, надеюсь, какой-то код прояснит это. Я пытаюсь создать свою собственную матричную математическую библиотеку для своего игрового движка, а не использую существующую, такую ​​как glm (опыт обучения). Я немного кода для справки:

template<size_t S1, size_t S2> struct matrix: std::array<std::array<float, S2>, S1>
{
    matrix()
    {
        *this = 0;
    }

    matrix<S1, S2>& operator=(const float& value)
    {
        for (uint32_t i = 0; i < S1; ++i)
        {
            for (uint32_t j = 0; j < S2; ++j)
            {
                this[i][j] = value;
            }
        }

        return *this;
    }

    // other operator overloads
};

struct vec2: matrix<1, 2>
{
    float& x()
    {
        return this->_M_elems[0][0];
    }

    float& y()
    {
        return this->_M_elems[0][1];
    }
};

struct vec3: matrix<1, 3>
{
    float& x()
    {
        return this->_M_elems[0][0];
    }
    float& y()
    {
        return this->_M_elems[0][1];
    }
    float& z()
    {
        return this->_M_elems[0][2];
    }
};

Я пытаюсь перегрузить операцию умножения (operator*) для моей структуры матрицы, чтобы при попытке умножения двух матриц получилось скалярное произведение двух. Пара правил выполнения точечного произведения на матрицах:

Количество столбцов 1-й матрицы должно равняться количеству строк 2-й матрицы.

и

Результат будет иметь то же количество строк, что и 1-я матрица, и столько же столбцов, что и 2-я матрица.

И вот я попробовал:

template<size_t S1, size_t S2> struct matrix: std::array<std::array<float, S2>, S1>
{
    matrix()
    {
        *this = 0;
    }

    matrix<S1, S2>& operator=(const float& value)
    {
        for (uint32_t i = 0; i < S1; ++i)
        {
            for (uint32_t j = 0; j < S2; ++j)
            {
                this[i][j] = value;
            }
        }

        return *this;
    }

    // other operator overloads

    matrix<S1, S3> operator*(const matrix<S2, S3>& multiplier)
    {
        matrix<S1, S3> dot_product;

        for (uint32_t i = 0; i < S1; ++i)
        {
            for (uint32_t j = 0; j < S2; ++j)
            {
                for (uint32_t k = 0; k < S3; ++k)
                {
                    dot_product[i][k] += (this[i][j] * multiplier[j][k]);
                }
            }
        }

        return dot_product;
    }
}

И я даже не уверен, является ли это правильным способом для работы с точечным произведением, поскольку он не компилируется с S3, который нигде не определен. У меня вопрос, как мне передать в качестве параметра функции matrix<S2, S3>, где S2 уже определен в структуре, а S3 - неизвестный размер?

Редактировать: Благодаря щедрой помощи я смог заставить свой код работать, для теста:

matrix<2, 3> test1;
matrix<3, 2> test2;

test1[0][0] = 1;
test1[0][1] = 2;
test1[0][2] = 3;
test1[1][0] = 4;
test1[1][1] = 5;
test1[1][2] = 6;
test2[0][0] = 6;
test2[0][1] = 5;
test2[1][0] = 4;
test2[1][1] = 3;
test2[2][0] = 2;
test2[2][1] = 1;

auto result = test1 * test2;

std::cout << test1 << std::endl;
std::cout << test2 << std::endl;
std::cout << result << std::endl;

выводит на консоль:

[ 1 2 3 ] 
[ 4 5 6 ]

[ 6 5 ] 
[ 4 3 ] 
[ 2 1 ]

[ 20 14 ] 
[ 56 41 ]

Что я и подтвердил здесь. Я смог распечатать вывод только на консоль из-за какого-то другого кода, не показанного здесь (для потомства)

1 Ответ

2 голосов
/ 17 апреля 2019
template<size_t S3>
matrix<S1, S3> operator*(const matrix<S2, S3>& multiplier)

Также ваш matrix<S1, S2>& operator=(const float& value) не так. Матрица, соответствующая числам с плавающей запятой, обычно диагональна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...