2012-01-31 1 views
5
struct Matrix(int row, int col){ /* ... */ } 

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

理由はmrefであることが性能のためです。明らかに、逆行列が必要になるたびに大きな行列がコピーされることは望ましくありません。これはこれまでのところうまくいきました。コンパイル時に 'ref'を使用するには?

しかし、それは逆に、コンパイル時に必要とされる状況で問題となっている:

mixin template A(){ 

    alias Matrix!(3, 3) Matrix3x3; 

    static Matrix3x3 computeSomeMatrix(){ } 

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

エラーを修正するには、私は非refにmを変更する必要があるが、それはその行列を意味し、 inverse()が呼び出されるたびにコピーされます。私は何をしますか?

+0

または単にrefとinverse以外の 'inverse()'バリアントを持つことができますか? – DejanLekic

+1

正確なエラーは何ですか? 'ref'はコンパイル時に動作するはずです。それはあなたがやっている何か他のものでしょう。 – Robert

+4

'auto ref'を試しましたか? –

答えて

4

2つのオプションのいずれかを表示します。 1つは、右辺値を取るバージョンを作成します。とにかく関数がrvaluesで動作しない場合は、しばしば迷惑です。単純なラッパーはあなたが必要とするすべてである:

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

は、パラメータのconstのネスがが一​​致していることに注意してください、またはあなたが無限再帰を取得するつもりです。

ただし、より良い解決方法はauto refです。これはそれが作成されたものです。適切な場合と非refたときに適切な

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

コンパイラは、あなたがそれを心配することなく、refを使用します。