C++ expression templates for slices

You need to account for the value category of your inner expressions.

You can do that with a trait to distinguish lvalues and rvalues, and a bunch of perfect forwarding.

template <typename T>
struct expression_holder {
    using type = T;
};

template <typename T>
struct expression_holder<const T> : expression_holder<T> {
};

template <typename T>
struct expression_holder<T &> {
    using type = const T &;
};

template <typename T>
struct expression_holder<T &&> {
    using type = T;
};

template <typename T>
using expression_holder_t = typename expression_holder<T>::type;

template<typename E1, typename E2>
class ElementWiseScalarProd : public ElementWiseScalarExpression< ElementWiseScalarSum<E1, E2> >
{
public:
    ElementWiseScalarProd(E1&& lhs, E2&& rhs) : m_lhs(std::forward<E1>(lhs)), m_rhs(std::forward<E2>(rhs)) {}
...
private:
    expression_holder_t<E1> m_lhs;
    expression_holder_t<E2> m_rhs;
};

template<typename E1, typename E2> 
ElementWiseScalarProd<E1, E2> scalar_prod(E1 && lhs, E2 && rhs) {
    return ElementWiseScalarProd<E1, E2>(std::forward<E1>(lhs), std::forward<E2>(rhs));
}