Removing the <:
from the type definition makes it work:
This works:
julia> struct Foo{T<:Real, S<:AbstractMatrix{T}}
data::S
n::Int
end
julia> Foo(A::AbstractMatrix{T}, n::Int) where {T<:Real} = Foo{T, typeof(A)}(A, n)
Foo
julia> Foo{T}(::UndefInitializer,n) where {T<:Real} = Foo(Matrix{T}(undef,n,n),n)
julia> Foo{Float64}(undef,2)
Foo{Float64,Array{Float64,2}}([0.0 0.0; 0.0 0.0], 2)
julia>
This does not:
julia> struct Foo{T<:Real, S<:AbstractMatrix{<:T}} # the difference is the <: here
data::S
n::Int
end
julia> Foo(A::AbstractMatrix{T}, n::Int) where {T<:Real} = Foo{T, typeof(A)}(A, n)
Foo
julia> Foo{T}(::UndefInitializer,n) where {T<:Real} = Foo(Matrix{T}(undef,n,n),n)
julia> Foo{Float64}(undef,2)
ERROR: UndefVarError: T not defined
Minimal example:
julia> struct Foo{T,S <: Vector{<:T}}
x :: S
end
julia> Foo{T}(::UndefInitializer) where T = Foo(Vector{T}(undef,2))
julia> Foo{Float64}(undef)
ERROR: UndefVarError: T not defined