Ошибка при получении копии на структуре, содержащей тип VectorN налгебры - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь использовать тип nalgebra VectorN для реализации некоторых измерений, не зависящих от размеров, но я получаю некоторые странные ошибки в отношении черты Copy.Приведенный ниже надуманный тестовый пример демонстрирует проблему:

extern crate nalgebra;

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

#[derive(Clone, Debug, Copy, PartialEq)]
pub struct LinearPathSegment<N: Real, D: DimName>
where
    DefaultAllocator: Allocator<N, D>,
{
    pub some_vec: VectorN<N, D>,
    pub some_scalar: N,
}

Клонируйте и выполните cargo build в этом репозитории, чтобы воспроизвести

Сообщение об ошибке, выданное компилятором (rustc 1.29.1 (b801ae664 2018-09-20)) это:

error[E0204]: the trait `Copy` may not be implemented for this type
  --> src/lib.rs:6:24
   |
6  | #[derive(Clone, Debug, Copy, PartialEq)]
   |                        ^^^^
...
11 |     pub some_vec: VectorN<N, D>,
   |     --------------------------- this field does not implement `Copy`

Я уверен, что VectorN действительно реализует Copy;следуя псевдонимам типа через цепочку VectorN<...> -> MatrixMN<...> -> Matrix<...>, мы видим, что Copy равно #[derive()] d для Matrix, что должно означать, что оно также получено для VectorN.Почему компилятор говорит иначе?Что мне нужно сделать, чтобы сделать VectorN копируемым?

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Вы должны добавить границу Owned<N, D>: Copy.Owned используется как часть псевдонима типа MatrixMN.Owned заканчивается псевдонимом типа для MatrixArray.

extern crate nalgebra;

use nalgebra::{DefaultAllocator, DimName, Real, VectorN};
use nalgebra::allocator::Allocator;
use nalgebra::storage::Owned;

#[derive(Clone, Debug, Copy, PartialEq)]
pub struct LinearPathSegment<N: Real, D: DimName>
where
    DefaultAllocator: Allocator<N, D>,
    Owned<N, D>: Copy,
{
    pub some_vec: VectorN<N, D>,
    pub some_scalar: N,
}

Real требует Copy и DimName требует Dim, что требует Copy, поэтому N и D не должны иметь явную границу Copy.Но по какой-то причине компилятор не может доказать, что MatrixArray равен Copy.Я подозреваю, что это происходит из-за ограничения GenericArray<N, Prod<R::Value, C::Value>>: Copy в его реализации Copy.

Другой вариант заключается в добавлении границы VectorN<N, D>: Copy.

Обратите внимание, что любой параметр вызывает любое использование вашей структурывстретить эту границу.Если это не то, что вам нужно, вы должны написать руководство impl для Copy с соответствующими границами, а не выводить его.

impl<N, D> Copy for LinearPathSegment<N, D>
where
    N: Real,
    D: DimName,
    DefaultAllocator: Allocator<N, D>,
    VectorN<N, D>: Copy,
{
}
0 голосов
/ 04 октября 2018

Получение Copy является особенным в этом случае, потому что Matrix является общим:

#[repr(C)]
#[derive(Hash, Clone, Copy)]
pub struct Matrix<N: Scalar, R: Dim, C: Dim, S> {
    /// The data storage that contains all the matrix components and informations about its number
    /// of rows and column (if needed).
    pub data: S,

    _phantoms: PhantomData<(N, R, C)>,
}

Маркер Copy реализуется, только если N, R, C иS также Copy.

Действительно, вы можете увидеть эту строку на странице документации Matrix:

impl<N: Copy + Scalar, R: Copy + Dim, C: Copy + Dim, S: Copy> Copy for Matrix<N, R, C, S>

В качестве более простого примера, этот код прекрасно компилируется:

#[derive(Clone, Copy)]
struct DummyWrapper<T>(T);

fn main() {
}

Но, конечно, вы можете копировать DummyWrapper, только если T тоже можно копировать:

#[derive(Clone, Copy)]
struct DummyWrapper<T>(T);

fn consume<T>(_t: T) {}

fn main() {
    // Ok
    let a = DummyWrapper(42);
    consume(a);
    consume(a);

    // Error: move occurs because `a` has type `DummyWrapper<std::string::String>`,
    // which does not implement the `Copy` trait
    let a = DummyWrapper(String::from("test"));
    consume(a);
    consume(a);
}

Чтобы сделать вашу структуру копируемой, я только догадываюсь,но вы должны добавить следующие границы:

N: Copy, D: Copy
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...