Error parametrizing type with DIm

I am trying to parameterize my Node type with an nalgebra::dimension::Dim trait. However, after getting an error, I changed the Dim trait to DimName. The following code is now giving a new error.

Here is the code and a link to run it.

use nalgebra::{
    base::dimension::DimName,
    base::VectorN,
    RealField
};

struct Node<T: RealField, D: DimName> {
    location: VectorN<T, D>,
}

The error:

error[E0277]: cannot multiply `typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>` to `<D as nalgebra::DimName>::Value`
 --> src/lib.rs:8:15
  |
8 |     location: VectorN<T, D>,
  |               ^^^^^^^^^^^^^ no implementation for `<D as nalgebra::DimName>::Value * typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>`
  |
  = help: the trait `std::ops::Mul<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>>` is not implemented for `<D as nalgebra::DimName>::Value`
  = note: required because of the requirements on the impl of `nalgebra::allocator::Allocator<T, D>` for `nalgebra::DefaultAllocator`

How might I resolve this or is there a more appropriate dimension trait to use?

1 Like

Hi!

Here is the correct code:

use nalgebra::{
    DimName,
    VectorN,
    RealField,
    DefaultAllocator,
    allocator::Allocator,
};

struct Node<T: RealField, D: DimName>
    where DefaultAllocator: Allocator<T, D> {
    location: VectorN<T, D>,
}

With nalgebra, the cannot multiply typenum::uint::UInt kind of errors often means that you are missing some DefaultAllocator: Allocator<*> traits. The idea is that because the code is generic wrt. the dimension of the vector, we need to explain to the compiler how to generate the internal storage of the vector/matrix. This is achieved by these DefaultAllocator: Allocator<*> bounds.

So if you store or create a VectorN<T, D>, you need a DefaultAllocator: Allocator<T, D> bound.

If you stored a MatrixMN<T, R, C> you need a DefaultAllocator: Allocator<T, R, C> bound.

If you store both, you need both, i.e, DefaultAllocator: Allocator<T, R, C> + Allocator<T, D>.

This is a bet verbose, but unfortunately necessary until Rust supports specialization completely.

1 Like