0

Suppose we have a matrix class which makes use of expression templates such that proxy objects are used to make it possible for the compiler to optimize compound expressions.

Now, it's quite natural to create a row class of the following form:

namespace detail
{
    template<class E>
    class row
        : public vector_expression<row<E>>
    {
    public:
        using size_type = size_type_t<E>;

        template<class F>
        row(F&& e, size_type i)
            : m_e(std::forward<F>(e)),
              m_i(i)
        {}

        result_of_call_operator_t<E&> operator()(size_type j) { return m_e(m_i, j); }
        result_of_call_operator_t<E const&> operator()(size_type j) const { return m_e(m_i, j); }

    private:
        E m_e;
        size_type const m_i;
    };
}

and a corresponding helper function of the following form:

template<class E, class =
    std::enable_if_t<detail::is_matrix_expression_v<E>>>
detail::row<E> row(E&& e, detail::size_type_t<E> i) {
    return { std::forward<E>(e), i };
}

The idea is that a row might be the row of an actual matrix object or a (temporal) matrix_expression.

What I want to do now is equipping row with an assignment operator such that we can assign (compatible) vector_expressions to a row. Of course, such an operator should be disabled, if the related matrix_expression of the row object is not "assignable".

Here's a first idea for a useful type trait:

template<class E, class F>
using is_assignable_t = decltype(std::declval<result_of_call_operator_t<E>>() = std::declval<result_of_call_operator_t<F>>());
template<class E, class F>
constexpr bool is_assignable_v = is_detected_v<is_assignable_t, E, F>;

Now, the problem is that we might have a column class and many similar classes too. So, I'm searching for a way to implement the idea described above in a way which doesn't forces me to add an assignment operator to each of these classes.

To be precise, I could equip row with the following operaotr:

template<class F,
    class = std::enable_if_t<is_assignable_v<E&, F>>>
row& operator=(vector_expression<F> const& e)
{
    /* ... */
    return *this;
}

However, I would need to add such an operator to the column class and any other class of this kind too.

To summarize, I would like to implement this at the vector_expression level such that a "compatible" (i.e. elements are convertible) vector_expression can be assigned to a "assignable" (in the above sense) vector_expression. How can we do that?

I've hided the implementation details above, but here is a Live demo of the stuff you need to answer my question.

0xbadf00d
  • 17,405
  • 15
  • 67
  • 107

1 Answers1

-1

In member class numeric::detail::row, already defined element(m_e) and index(m_i), then my code like this :

        template<class F,
            class = std::enable_if_t<is_assignable_v<E&, F>>>
            row& operator=(vector_expression<F> const& e)
        {
            for (size_type i = 0; i < m_e.row_size(); ++i)
            {
                m_e(m_i, i) = e(i);
            }
            return *this;
        }