Hi,
I can’t figure out how to use a parametric type inside a constructor. Namely, the following single commented line can’t be used:
struct Foo{T<:Real, S<:AbstractMatrix{<:T}} <: AbstractArray{T, 4}
data::S
n::Int
function Foo{T, S}(data, n) where {T<:Real, S<:AbstractMatrix{<:T}}
Base.require_one_based_indexing(data)
new{T, S}(data, n)
end
end
function Foo(A::AbstractMatrix{T}, n::Int) where {T<:Real}
return Foo{T, typeof(A)}(A, n)
end
function Foo{T}(::UndefInitializer, n::Int) where {T<:Real}
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
The function Foo{T}(::UndefInitializer, n::Int) where {T<:Real}
works as long as T
is not mentioned anywhere in its body. Otherwise, a UndefVarError: T not defined
is thrown:
# ; is needed because I'm omitting the definitions of size and
# getindex, which are complicated and required by the REPL to
# show AbstractArrays
julia> Foo{Float64}(undef, 2);
ERROR: UndefVarError: T not defined
Stacktrace:
[1] Foo{Float64,S} where S<:(AbstractArray{#s1,2} where #s1<:Float64)(::UndefInitializer, ::Int64) at ./REPL[5]:7
[2] top-level scope at REPL[6]:1
Version information:
julia> versioninfo()
Julia Version 1.4.1
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-8.0.1 (ORCJIT, broadwell)
Environment:
JULIA_NUM_THREADS = 4
What am I doing wrong?