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_expression
s to arow
. Of course, such an operator should be disabled, if the relatedmatrix_expression
of therow
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.