My mistake, I copied the code and forgot to change the commented lines.
It seems clear to me that what I pointed in your original MWE cannot be exactly same that affected OP’s MWE. In OP’s MWE the problem happens because somehow in the first function called T
is not recognized within the body of the first function called.
@schneiderfelipe Than for your kind words, but while I think I got it right for @lmiq MWE, I do not think I solved your original problem.
Now… this is funny:
julia> struct Foo{T<:Real, S<:AbstractMatrix{<:T}}
data::S
n::Int
function Foo{T, S}(data, n) where {T<:Real, S<:AbstractMatrix{<:T}}
println("Foo{T, S}(data, n)")
Base.require_one_based_indexing(data)
new{T, S}(data, n)
end
end
function Foo(A::AbstractMatrix{T}, n::Int) where {T<:Real}
println("Foo(A, n)")
return Foo{T, typeof(A)}(A, n)
end
# Changed the signature below to take both T and S even if S is not used
function Foo{T, S}(::UndefInitializer, n::Int) where {T<:Real, S <: AbstractMatrix{<:T}}
println("Foo{T, S}(undef, n)")
d = fld(n * (n + 1), 2)
# The next two lines should substitute each other,
# but the commented one throws an error.
A = Matrix{T}(undef, d, d) # UndefVarError: T not defined
# A = zeros(d, d)
return Foo(A, n)
end
julia> Foo{Float64, Matrix{Float64}}(undef, 2)
Foo{T, S}(undef, n)
Foo(A, n)
Foo{T, S}(data, n)
Foo{Float64,Array{Float64,2}}([0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], 2)
Why? Why the hell?
My guess now is that, maybe, just maybe, we are not allowed to define an outer constructor taking less type parameters than the struct
itself?