Cxx.jl
Cxx.jl copied to clipboard
Clean up the separation of a sized value and a C++ type
I'm having a trouble with multiple dispatch with nested Cxx templated types (e.g. StdVector{StdVector{T}}
). A minimum illustration of the problem is as follows:
julia> import CxxStd: StdVector
julia> f{T}(v::StdVector{StdVector{T}}) = println("vector of vectors")
julia> vv = icxx"std::vector<std::vector<double>>();";
julia> f(vv)
ERROR: MethodError: `f` has no method matching f(::Cxx.CppValue{Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::vector")},Tuple{Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::vector")},Tuple{Float64,Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::allocator")},Tuple{Float64}},(false,false,false)}}},(false,false,false)},Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::allocator")},Tuple{Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::vector")},Tuple{Float64,Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{symbol("std::__1::allocator")},Tuple{Float64}},(false,false,false)}}},(false,false,false)}}},(false,false,false)}}},(false,false,false)},24})
Dispatching with non-nested types works as expected:
julia> f(v::StdVector) = println("vector")
julia> v = icxx"std::vector<double>();";
julia> f(v)
vector
Would it be possible to dispatch with nested Cxx templated types like StdVector{StdVector{T}}
?
FYI:
julia> v = icxx"std::vector<double>();";
julia> isa(v, StdVector{Cdouble})
true
julia> vv = icxx"std::vector<std::vector<double>>();";
julia> isa(vv, StdVector{StdVector{Cdouble}})
false
julia> isa(vv, StdVector{StdVector})
false
julia> isa(vv, cxxt"std::vector<std::vector<double>>")
true
In julia arrays, it works as expected:
julia> x = Vector{Float64}();
julia> isa(x, Vector{Float64})
true
julia> xx = Vector{Vector{Float64}}();
julia> isa(xx, Vector{Vector{Float64}})
true
I think the following should work:
f{T}(v::StdVector{StdVector{T}}) = println("vector of vectors")
oops, sorry I meant the one that you pointed out, but it didn't work to me. Updated issue description.
I haven't tried the latest Cxx.jl since I wasn't able to build it. I'm using a bit old Cxx.jl ff0bec6 (sorry if this doesn't happen on the latest Cxx.jl).
Hmm, I'll take a look later today.
For the record, I built the latest Cxx.jl (https://github.com/Keno/Cxx.jl/commit/bce1fdf7b354f3984d9dd39ae83fd6f9e6ef9930) on top of Julia master (https://github.com/JuliaLang/julia/commit/d4749d2ca168413f3db659950a1855530b58686d) based on llvm 3.7.1 and confirmed that this behavior still happens.
Unfortunately there is no good way to encode this currently because the StdVector
type needs to encode size information, but the type parameter itself does not. I may try to fix this when I revisit the type hierarchy mapping, but for now it's not quite possible.
I see. Thank you for the clarification.
The plan is to fix this by introducing derived type parameters in Base, so you could write:
type CxxValue{T}
data::NTuple{UInt8,cxxsizeof(T)}
end