开发者

Why compiler choose the const method instead of non-const?

I'm trying to implement a three dimensional tensor using uBlas matrix from boost as a backend. One of the function is getting a reference to a slice and enables an easy assignment of matrix.

Below is a fragment of tensor class:

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_)));

    }
}

The layout_type looks like:

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
    开发者_如何学JAVA    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);
        }
     }
} 

And the use-case is as below:

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

The problem exists on this line:

    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_)));

When the trans and project functions are used together the compiler choose const overload of project and trans and I cannot do assignment like above. However, if I leave only project the non-const method is used and everything works. Unfortunately, the transposition of a slice is necessary, because of designed storage layout (mapping to the two dimensional matrix).

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);

Is there any solution to indicate a right function overload? Or I made an error somewhere?


When a const as well as non-const version is available, then the compiler chooses theconst version, if the object itself is const. If the object is non-const, then the compiler chooses the non-const version. That is how the functions are resolved.

So in your code, if the const version is selected, then the object must be const itself.

Also note that in a const member function, this is a const pointer, and whatever member data you return from it, is also const.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜