2016-08-23 100 views
1

我正在爲Hermitian matrices寫一個類。這是一個複雜的矩陣,它只有n*(n+1)/2獨立的複數(忽略對角線的細節完全是真實的)。C++:代理設置/獲取數組值與複合共軛

我的計劃是隻寫上三角形的元素,其中行號與列號相比滿足條件滿足條件:row >= column。但是,這需要像代理一樣?我不知道如何實現這一點。問題如下:

說我執行成員函數at(int row, int column)來訪問一個元素。

template<typename T> 
std::complex<T>& HermitianMatrix<T>::at(long row, long column) 
{ 
    if(row >= column) 
     return this->_matrix[ElementIndex(row,column)]; 
    else 
     return std::conj(this->_matrix[ElementIndex(column,row)]); 
} 

其中ElementIndexrowcolumn和輸入轉換到陣列std::complex<T>* _matrix = new std::complex<T>(...)在的位置。當然,這個方法返回一個引用。上面看到的代碼對於矩陣的下三角部分不起作用,因爲參考在返回後消失了。

什麼是正確和最有效的方式來實現這一點,使我有某種「管道」的下三角矩陣部分總是經過std::conj爲設置和獲得?

如有需要,請索取更多信息。謝謝。

+0

if中的塊應該是'ElementIndex(column,row)',不應該嗎? – Holt

+0

@Holt是的。我修好了它。謝謝。 –

回答

2

遵循Franck的例子,我建議返回一個包裝類(或結構),它包裝對元素的引用並記住布爾標誌以記住是否需要共享該數字。

喜歡的東西[注意:未測試]

template <typename T> 
struct cWrapper 
{ 
    bool    c; 
    std::complex<T> & r; 

    cWrapper (bool c0, std::complex<T> & r0) : c{c0}, r{r0} 
    { } 

    operator std::complex<T>() const 
    { return c ? std::conj(r) : r; } 

    cWrapper & operator= (const std::complex<T> & r0) 
    { 
    r = (c ? std::conj(r0) : r0); 

    return *this; 
    } 
}; 

和你的函數可以成爲[編輯:在問題中相應的編輯(行/列反轉的其他情況下)後修改]

template<typename T> 
cWrapper<T> HermitianMatrix<T>::at(long row, long column) 
{ 
    if(row >= column) 
     return cWrapper<T>(false, this->_matrix[ElementIndex(row,column)]); 
    else 
     return cWrapper<T>(true, this->_matrix[ElementIndex(column,row)]); 
} 
0

考慮到的std ::連詞()不返回一個參考,你有兩個選擇:

  • 不回你的函數的引用,而是一個價值
  • 實現自己的版本std :: conj()函數返回一個引用
+0

但是我怎麼能區分set和get?如果用戶設置了該值,我希望將該值作爲共軛輸入矩陣。 –

1

你可以實現一個屬性類並返回這個類的一個對象。

template <typename T> 
struct ComplexGetter { 
    std::complex<T>* ref; 
    std::complex<T> conj; 

    ComplexGetter(std::complex<T>& reference) : ref(&reference) {} 
    ComplexGetter(const std::complex<T>& conjugate) : ref(nullptr), conj(conjugate) {} 

    operator std::complex<T>() const { return ref ? *ref : conj; } 
    operator=(const std::complex<T>& source) 
    { if (ref) *ref = source; 
     else { ... /* do something */ } 
    } 
}; 

它可以被分配和自動轉換。