【问题标题】:C++: Proxy to set/get array value with a complex conjugateC ++:使用复杂共轭设置/获取数组值的代理
【发布时间】:2016-08-23 12:54:27
【问题描述】:

我正在为Hermitian matrices 编写课程。这是一个只有n*(n+1)/2 独立复数的复矩阵(忽略对角线完全为实数的细节)。

我的计划是只写上三角元素,其中行号与列号相比满足条件满足规则: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&lt;T&gt;* _matrix = new std::complex&lt;T&gt;(...) 中的位置。当然,这个方法返回一个引用。您在上面看到的代码不适用于矩阵的下三角部分,因为返回后引用消失了。

实现这一点的正确和最有效的方法是什么,这样我有一些用于下三角矩阵部分的“管道”总是通过std::conj 进行设置和获取?

如果需要,请询问更多信息。谢谢。

【问题讨论】:

  • if 中的块应该是ElementIndex(column, row),不是吗?
  • @Holt 是的。我修好了它。谢谢。

标签: c++ c++11 reference c++14 proxy-classes


【解决方案1】:

按照 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)]);
 }

【讨论】:

    【解决方案2】:

    您可以实现一个属性类并返回该类的一个对象。

    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 */ }
        }
    };
    

    可以赋值并自动转换。

    【讨论】:

      【解决方案3】:

      考虑到 std::conj() 不返回引用,您有两种选择:

      • 不要在函数中返回引用,而是返回值
      • 实现您自己版本的 std::conj() 函数,该函数返回一个引用

      【讨论】:

      • 但是如何区分 set 和 get 呢?如果用户设置了值,我希望将值作为共轭传递到矩阵。
      猜你喜欢
      • 1970-01-01
      • 2013-03-21
      • 2022-11-19
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      • 2015-07-24
      • 2013-06-05
      • 1970-01-01
      相关资源
      最近更新 更多