Handling references to `expressions` in a `vector_binary_operation` class without unnecessary copies

后端 未结 1 1141
面向向阳花
面向向阳花 2021-01-24 02:20

I\'m trying to implement a simple vector class which uses expression templates in order to avoid that expressions such as vector w = x + y + z are impl

相关标签:
1条回答
  • 2021-01-24 03:04

    I was facing a similar decision in my expression template code quite some time ago. The choice of how to store the wrapped arrays is thereby of central importance and should be made with care. But let's assume you already settled for references: that is, if you have code like

    vector a;
    vector b;
    auto c = a + b;
    

    a and b are stored by const-reference. This implies that as long as you use c, the original vectors have to be kept alive. (Other choices would be store-by-value, which can be expensive, or store-by-(wrapped)-shared-pointer, which let's you use c even if a or b left their scope but comes with a call overhead.)

    Ok, but now as you settled for references, you obviously want to avoid references to a temporary. For that, C++ move semantics offers already anything you need:

    template<typename E1, typename E2>
    auto operator+(E1&& e1, E2&& e2)
    {
         using value_type = decltype(e1[0] + e2[0]);
         return vector_binary_operation<E1, E2, std::plus<value_type> >
                       {std::forward<E1>(e1), std::forward<E2>(e2), std::plus<value_type>{}};
    }
    

    The difference to your code is in the type deduction of the used rvalue references E1&& and E2&&. Their purpose is to indicate whether the function got a valid and named object or a temporary. Based on this information, in this function you can make the choice how to store the passed references in the returned expression classes.


    For example, if you now add two vectors

    auto c = a + b;
    

    E1 and E2 will be deduced both as vector&. On the opposite, if you have

    auto d = (a + b) + b;
    

    E1 is vector_binary_operation<vector&, vector&, std::plus<> > -- no reference here -- whereas E2 is still vector&.

    0 讨论(0)
提交回复
热议问题