2011-08-26 223 views
0

我想實現一個使用uBlas矩陣作爲後端的三維張量。其中一個功能是獲取對切片的引用,並可以輕鬆分配矩陣。爲什麼編譯器選擇const方法而不是非const?

下面是張類的一個片段:

template<class L, class M> 
class tensor { 
public: 
    typedef L layout_type; 
    typedef std::size_t size_type; 
    typedef M array_type; 

private: 
    size_type size1_; 
    size_type size2_; 
    size_type size3_; 

    array_type data_; 
public: 

    /** 
    * Return a constant reference to the internal storage of a dense tensor, i.e. the raw data 
    * It's type depends on the type used by the tensor to store its data 
    */ 
    BOOST_UBLAS_INLINE 
    const array_type &data() const { 
     return data_; 
    } 
    /** 
    * Return a reference to the internal storage of a dense tensor, i.e. the raw data 
    * It's type depends on the type used by the tensor to store its data 
    */ 
    BOOST_UBLAS_INLINE 
    array_type &data() { 
     return data_; 
    } 

    /**@}*/ 

    /** 
    * @name Slices' access 
    * Accessors for slices across each dimension 
    */ 
    /**@{*/ 
    BOOST_UBLAS_INLINE 
    typename layout_type::template slice<1>::matrix_slice_type 
    at_dim1_slice(uint32_t i) { 
     return ublas::trans(ublas::project(data(), layout_type::template slice<1>::coord1(i, size1_, size2_, size3_), 
       layout_type::template slice<1>::coord2(i, size1_, size2_, size3_))); 

    } 
} 

的layout_type樣子:

template<class M> 
struct basic_dim2_major { 
    typedef M matrix_type; 

    template<int DIM, class DUMMY = void> 
    struct slice { 
    }; 
    template<class DUMMY> struct slice<1, DUMMY> { 

     struct trans { 
      template<class T> 
      auto operator()(T &x) ->decltype(ublas::trans(x)) 
      { 
       return ublas::trans(x); 
      } 
     }; 

     typedef ublas::matrix_slice<matrix_type> matrix_slice_type; 
     typedef typename std::result_of<trans(matrix_slice_type&)>::type Type; 

     static BOOST_UBLAS_INLINE 
     Type 
     orient(matrix_slice_type &data){ 
      return ublas::trans(data); 
     } 

     static BOOST_UBLAS_INLINE 
     ublas::slice coord1(size_type i, size_type size_i, size_type size_j, size_type size_k) { 
      return ublas::slice(i, size_i, size_k); 
     } 
     static BOOST_UBLAS_INLINE 
     ublas::slice coord2(size_type i, size_type size_i, size_type size_j, size_type size_k) { 
      return ublas::slice(0, 1, size_j); 
     } 
    } 
} 

及使用情況如下:

ublas::matrix slice1(3,4); 
tensor<> t(2,3,4); 
t.at_dim1_slice(0) = slice1; 

問題的存在在這條線上:

return ublas::trans(ublas::project(data(), layout_type::template slice<1>::coord1(i, size1_, size2_, size3_), 
     layout_type::template slice<1>::coord2(i, size1_, size2_, size3_))); 

當trans和project函數一起使用時,編譯器會選擇項目和trans的const超載,我不能像上面那樣進行賦值。但是,如果我只留下項目,則使用非const方法,並且一切正常。不幸的是,由於設計的存儲佈局(映射到二維矩陣),切片的換位是必要的。

const matrix_slice<const M> project (const M &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2); 
matrix_slice<M> project (matrix_slice<M> &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2); 

是否有任何解決方案來指示正確的功能過載?或者我在某個地方犯了一個錯誤?

+0

「但是,我...這是一個片段」啊,他是_so close_ –

+0

介意完成你的第三句話? –

+0

我對語言錯誤感到抱歉。 – przemkovv

回答

0

當const和non-const版本可用時,如果對象本身是const,編譯器將選擇const版本。如果對象是非const的,那麼編譯器會選擇非const的版本。這就是功能如何解決。

因此,在您的代碼中,如果選擇了const版本,那麼該對象必須是const本身。

另請注意,在一個const成員函數中,this是一個常量指針,並且您從中返回的任何成員數據也是const

+1

我非常小心地檢查了常量,我認爲它應該是正確的。正如我寫的,如果我只使用ublas :: project()(不是ublas :: trans(ublas :: project())),那麼一切正常。這兩個函數都有非常量重載。 – przemkovv

相關問題