【问题标题】:Implementing an assignment operator for a row class in a matrix library which uses expression templates为使用表达式模板的矩阵库中的行类实现赋值运算符
【发布时间】:2017-04-19 21:12:11
【问题描述】:

假设我们有一个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_expressions 分配给row。当然,如果row 对象的相关matrix_expression 不是“可分配”的,则应该禁用这样的运算符。

这是一个有用的类型特征的第一个想法:

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 .我们该怎么做?

我已经隐藏了上面的实现细节,但here 是一个现场演示,您需要回答我的问题。

【问题讨论】:

    标签: c++ c++17 typetraits expression-templates


    【解决方案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;
            }
    

    【讨论】:

      猜你喜欢
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-27
      • 2021-08-15
      • 2019-06-30
      • 2016-02-16
      相关资源
      最近更新 更多