First, there is another problem with your code. The constructor that should work with your definition is RegularGrid{Float64}((2,3))
, i.e. with the dims
specified as a tuple. However, this yields an error, because your type was defined as RegularGrid{N,T}
with N
first. But if you want an incomplete type specification with only T
, you need to have T
as first parameter (note AbstractArray{T,N}
).
Then, to get the constructor you want, you need to use Vararg
, but this does not need to be an inner constructor.
abstract type AbstractDomain{T<:Real,N} end
struct RegularGrid{T<:Real,N} <: AbstractDomain{T,N}
dims::Dims{N}
origin::NTuple{N,T}
units::NTuple{N,T}
end
RegularGrid{T}(dims::Dims{N}) where {N,T<:Real} =
RegularGrid{T,N}(dims, (zeros(T, length(dims))...), (ones(T, length(dims))...))
RegularGrid{T}(dims::Vararg{Int,N}) where {N,T<:Real} = RegularGrid{T}(dims)
Note that the last definition looks like it is calling itself. This is not true however. In the left, dims
is a Vararg
, i.e. multiple arguments. If you would not be interested in N
, you could write it as dims::Int...
. On the right hand side, when using the vararg dims
in the function body, the different arguments to which it correspond will be collected in a tuple. Hense, on the right hand side dims
is now NTuple{N,Int}===Dims{N}
. This function call will then be passed on to the constructor you had written.