Multiple dispatch constructor not multiple dispatching?

I’m trying to do multiple dispatch magic with various ways of representing a geometric transformation matrix. I have:

using StaticArrays

struct Quaternion{T<:Real}
    s::T
    v1::T
    v2::T
    v3::T
end

mutable struct transform
    pos::SVector{3, Cdouble}
    rot::SVector{4, Cdouble}
end

transform(pos::SVector{3, Cdouble}, q::Quaternion) = transform(pos, SVector{4, Cdouble}([q.v1, q.v2, q.v3, q.s]))

I can successfully create a transform struct by doing the normal thing:

T = transform([0., 0., 0.], [0., 0., 0., 1.])

but if I try

Q = Quaternion(1., 0., 0., 0.)
T = transform([0., 0., 0.], Q)

I get the error

ERROR: MethodError: Cannot `convert` an object of type Orientation.Quaternion{Float64} to an object of type StaticArrays.SArray{Tuple{4},Float64,1,4}
This may have arisen from a call to the constructor StaticArrays.SArray{Tuple{4},Float64,1,4}(...),
since type constructors fall back to convert methods.

…which makes me think that Julia is not attempting to call the constructor I defined as taking a Quaternion type, but is instead trying to convert() Q directly to an SVector.

This should be easy, which makes me think I am missing something obvious. But for the life of me I can’t see it.

Please provide enough code so that the error can be reproduced by just copy pasting things into a REPL.

Ok, all that is needed was using StaticArrays.

Edit:

Your transform function needs a SVector as the first argument and you give it a normal Vector. Use e.g:

 T = transform(@SVector([0., 0., 0.]), Q)

Right now it will fail to match your outer constructor and try use the inner one (which tries to convert arugments).

2 Likes

“Please provide enough code so that the error can be reproduced by just copy pasting things into a REPL.”

Yes, I have modified the code to make that explicit. Thanks.

I think the issue is the first argument of your constructor. What you are trying to pass in is a Vector, but you wrote your constructor to require an SVector. Try annotating that first type with AbstractVector instead.

1 Like

Aha! Yes, that’s it. Thanks.