user12291970
user12291970

Reputation:

providing a default argument to a function, but that argument is a struct

struct mat4x4
{
    float m[4][4] = {0};
};

Basically, I have function to multiply a 4x4 matrix.

mat4x4 matrix_matrix(mat4x4 m1, mat4x4 m2)
{
    mat4x4 product.m[someValue][someValue] = do_calculations_and_get_product();
    return product;
} 

So what I was thinking is to take a third mat4x4 as argument by reference, save the product in that new matrix and return that matrix. But that means a third argument must be passed while calling it. I want to be able to call it by passing only 2 matrices and expect a product matrix as an output AND if third matrix is given, I want it to save the results to that third matrix and also return that matrix. From reading some of the other posts I came up with this

mat4x4 matrix_matrix(mat4x4 m1, mat4x4 m2, const mat4x4 & m3 = mat4x4{})
{
    m3.m[somevalue][somevalue] = do_calculations_and_get_product();
    return m3;
}

but I am getting an error: expression must be a modifiable lvalue, with a red wiggly line under m3. I don't really know what I am doing and need someone to help me. Thanks

Removing const gives the following error:

initial value of reference to non-const must be an lvalue

with a red wiggly line under mat4x4{} in function defination.

Upvotes: 2

Views: 69

Answers (2)

Sam Varshavchik
Sam Varshavchik

Reputation: 118340

With a compiler supporting C++17 this becomes a simple matter of using std::optional with std::reference_wrapper. Implicit conversions do all the hard work for you.

#include <optional>
#include <utility>
#include <functional>

struct mat4x4
{
    float m[4][4] = {0};
};

mat4x4 matrix_matrix(mat4x4 m1, mat4x4 m2,
             std::optional<std::reference_wrapper<mat4x4>
             > m3=std::nullopt)
{
    mat4x4 new_m;

    // Calculate something in new_m;

    if (m3)
        *m3=new_m;

    return new_m;
}

void test()
{
    mat4x4 m1, m2, m3, mret;

    mret=matrix_matrix(m1, m2);

    mret=matrix_matrix(m1, m2, m3);
}

Upvotes: 3

Thomas Sablik
Thomas Sablik

Reputation: 16451

You could use overloads:

struct mat4x4
{
    float m[4][4] = {0};
};

// Overload without reference
mat4x4 matrix_matrix(mat4x4, mat4x4)
{
    mat4x4 m3;
    m3.m[somevalue][somevalue] = do_calculations_and_get_product();
    return m3;
}

// Overload with reference
mat4x4 matrix_matrix(mat4x4, mat4x4, mat4x4 &m3)
// or do you want to return a reference?
// mat4x4 &matrix_matrix(mat4x4, mat4x4, mat4x4 &m3)
{
    m3.m[somevalue][somevalue] = do_calculations_and_get_product();
    return m3;
}

Upvotes: 0

Related Questions