我想實現一個使用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);
是否有任何解決方案來指示正確的功能過載?或者我在某個地方犯了一個錯誤?
「但是,我...這是一個片段」啊,他是_so close_ –
介意完成你的第三句話? –
我對語言錯誤感到抱歉。 – przemkovv