Как использовать 'ref' во время компиляции? - PullRequest
5 голосов
/ 31 января 2012
struct Matrix(int row, int col){ /* ... */ }

// finds the inverse using Gauss–Jordan elimination
pure M inverse(M)(const ref M m){ /* ... */ }

Причина m в ref заключается в производительности.Очевидно, я не хочу, чтобы большие матрицы копировались каждый раз, когда требуется обратное, и до сих пор это работало нормально.

Но это стало проблемой в ситуациях, когда обратное требуется во время компиляции:

mixin template A(){

  alias Matrix!(3, 3) Matrix3x3;

  static Matrix3x3 computeSomeMatrix(){ }

  immutable Matrix3x3 _m = computeSomeMatrix();
  immutable Matrix3x3 _m_1 = inverse(computeSomeMatrix());  // error
}

Чтобы исправить ошибку, мне нужно изменить m на non-ref, но это означает, что матрицы будут копироваться при каждом вызове inverse().Что мне делать?

1 Ответ

4 голосов
/ 01 февраля 2012

Я вижу один из двух вариантов.Во-первых, создать версию, которая принимает значение.Часто раздражает, когда функция все равно не работает со значениями.Все, что вам нужно, - это простая оболочка:

pure M inverse(M)(const ref M m){ /* ... */ }
pure M inverse(M)(const M m){ inverse(m); }

Будьте осторожны, если совпадение параметров совпадает, иначе вы получите бесконечную рекурсию.

Однако лучшерешение будет использовать auto ref.Это то, для чего он был создан.

pure M inverse(M)(const auto ref M m){ /* ... */ }

Затем компилятор будет использовать ref, когда это уместно, и не-1011 *, когда это уместно, и вам не придется об этом беспокоиться.

...