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