Реализация оператора присваивания для класса строк в матричной библиотеке, которая использует шаблоны выражений

Предположим, у нас есть matrix Класс, который использует шаблоны выражений так, что прокси-объекты используются, чтобы позволить компилятору оптимизировать составные выражения.

Теперь вполне естественно создать row класс следующей формы:

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

и соответствующая вспомогательная функция следующего вида:

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

Идея в том, что row может быть строкой фактического matrix объект или (временный) matrix_expression,

То, что я хочу сделать сейчас, это оборудование row с оператором присваивания, так что мы можем назначить (совместимый) vector_expressionс row, Конечно, такой оператор должен быть отключен, если matrix_expression из row объект не "присваивается".

Вот первая идея для полезной черты типа:

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

Теперь проблема в том, что мы могли бы иметь column класс и много похожих классов тоже. Итак, я ищу способ реализовать идею, описанную выше, таким образом, чтобы не заставлять меня добавлять оператор присваивания в каждый из этих классов.

Если быть точным, я мог бы оборудовать row со следующим операотр:

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

Однако мне нужно добавить такой оператор в column класс и любой другой класс такого рода тоже.

Подводя итог, я хотел бы реализовать это на vector_expression уровень, такой что "совместимый" (т.е. элементы являются конвертируемыми) vector_expression может быть назначен на "присваиваемый" (в вышеприведенном смысле) vector_expression, Как мы можем сделать это?

Я скрыл подробности реализации выше, но здесь есть живая демонстрация того, что вам нужно, чтобы ответить на мой вопрос.

1 ответ

В классе участника numeric::detail::row, уже определенный элемент (m_e) и индекс (m_i), тогда мой код выглядит так:

        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;
        }
Другие вопросы по тегам