2015-07-21 4 views
2

Я пытаюсь скопировать данные из matrixA в matrixB в функции M, но я получил ошибку:передавая массив по ссылке в D

Код:

double matrixA[5][5] = [ [ 1.0, 2.0, 3.0, 4.0, 5.0 ], 
         [ 1.0, 2.0, 3.0, 4.0, 5.0 ], 
         [ 1.0, 2.0, 3.0, 4.0, 5.0 ], 
         [ 1.0, 2.0, 3.0, 4.0, 5.0 ], 
         [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ]; 
double matrixB[][]; 

void M(double[][] s, ref double[][] d, int row, int col) 
{ 
    d.length = row; 

    foreach (i; 0 .. d.length) 
     d[i].length = col; 

    d = s; 
} 

void main() 
{ 
    M(matrixA, matrixB, 5, 5); 
} 
+0

Было бы проще помочь вам, если вы предоставили код, с которым работаете. То, что у вас здесь, не будет компилироваться, даже если то, что вы пытались сделать, было правильным, поскольку вы использовали '...' в определениях массивов и вы вызывали 'M' вне любой функции и с аргументами, которые не существуют , –

+0

вы можете рассмотреть ... как [1.0, 2.0, 3.0, 4.0, 5.0], я пытаюсь вызвать M внутри main – sp4

ответ

0

В настоящее время делает многомерное динамические массивы хорошо играют со статическими массивами, это немного сложно.

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

void M(T)(T s, ref double[][] d, int row, int col) 
    if (is(typeof(s[0][0]) : double)) 
{ } 

Это заявление говорит о том, что источник s может быть любого типа T такие, что индексация T на 0,0 возвращает double (или что-то неявно конвертируемое в double.

Однако тело вашей функции не будет работать как представлено. Вы не можете просто назначить s d, если они могут быть разных размеров. Это может быть ближе к тому, что вы ищете:

{ 
    d.length = row; 

    foreach(i ; 0 .. d.length) 
    d[i] = s[i][0..col].dup; 
} 
1

У вас, кажется, есть две проблемы. Один с ref и один с попыткой неявного преобразования, которое не сработает.

С ref в D тип должен точно соответствовать. Неявное преобразование не сокращает его. Так, например, если у вас есть

int[5] a = [1, 2, 3, 4, 5]; 
int[] b = a; 

и у вас есть

void foo(int[] bar) {} 

, то обе эти линии будет составлять

foo(a); 
foo(b); 

, так как статический массив неявно преобразуется в динамический один, но если вы измените его так, чтобы foo принял аргумент по ref

void foo(ref int[] a) {...} 

затем

foo(a); // won't compile, because a is int[5], not int[] 
foo(b); // compiles, because b is int[] 

Так что, если у вас есть функция, которая принимает ref double[][], вы должны передать его double[][]. Ничто, что неявно преобразуется в double[][], будет работать.

Теперь это хуже, потому что вы передаете ему double[5][5], который неявно конвертируется в double[][]. Итак, даже если ref принял неявные преобразования, ваш код не сработает, и даже если вы удалили ref, ваш код не сработает. Одномерный статический массив может быть разрезан (неявно или явно), чтобы получить динамический, но вы не можете срезать многомерный статический массив, чтобы получить динамический.

double[5] a; 
double[] b = b; // compiles 
double[] c = a[]; // compiles 

double[5][5] d; 
double[][] e = d; // does not compile 
double[][] f = d[]; // does not compile 

AFAIK, если вы хотите назначить double[5][5] к double[][], вы должны были бы сделать что-то вроде

double[5][5] a; 
double[][] b; 

foreach(i; row; a) 
    b[i] = row[]; 

Некоторые работы было сделано в последнее время на поддержку пользовательских типов с мульти- так что может быть возможно нарезать double[5][5] на double[][] с синтаксисом, о котором я не знаю, но это может быть то, что работает только с определенными пользователем типами. Несмотря на это, нет никакого неявного преобразования из double[5][5] в double[][], а неявные преобразования не работают с ref.

Смежные вопросы