Skip to main content

I've been reading Item 6Item 6 from Scott Meyers' Effective Modern C++ andScott Meyers' Effective Modern C++ and noticed that he mentioned a technique called "expression templates"expression templates. I've decided to give it a try and implemented a vector that supports addition and subtraction:

The main advantage of this solution is that in the line Vec<int> v4 = v1+v2-v3; no additional temporaries of type Vec are created, which increases performance.

I'd be grateful if someone could point potential drawbacks and possible further improvements of this code.

I've been reading Item 6 from Scott Meyers' Effective Modern C++ and noticed he mentioned a technique called "expression templates". I've decided to give it a try and implemented a vector that supports addition and subtraction:

The main advantage of this solution is that in the line Vec<int> v4 = v1+v2-v3; no additional temporaries of type Vec are created which increases performance.

I'd be grateful if someone could point potential drawbacks and possible further improvements of this code.

I've been reading Item 6 from Scott Meyers' Effective Modern C++ and noticed that he mentioned a technique called expression templates. I've decided to give it a try and implemented a vector that supports addition and subtraction:

The main advantage of this solution is that in the line Vec<int> v4 = v1+v2-v3; no additional temporaries of type Vec are created, which increases performance.

I'd be grateful if someone could point potential drawbacks and possible improvements of this code.

Return type deduction for normal functions is a C++14 feature.
Link
Morwenn
  • 20.2k
  • 3
  • 69
  • 132
Source Link

C++ vector that uses expression templates technique to increase performance of mathematical expressions

I've been reading Item 6 from Scott Meyers' Effective Modern C++ and noticed he mentioned a technique called "expression templates". I've decided to give it a try and implemented a vector that supports addition and subtraction:

#include <iostream>
#include <vector>

template<typename T>
class Vec
{
public:
    std::vector<T> data;

    typedef typename std::vector<T>::size_type size_type;
    
    Vec(size_type size): data(size)
    {
    }

    Vec(const std::initializer_list<T>& elements): data(elements.size())
    {
        size_type i = 0;
        for (const auto& el: elements)
        {
            data[i++] = el;
        }
    }

    template<typename VecOperation>
    Vec(const VecOperation& vo): data(vo.t2.data.size())
    {
        for (size_type i = 0; i < data.size(); ++i)
        {
            data[i] = vo[i];
        }
    }

    T operator[](size_type i) const
    {
        return data[i];
    }
};

template<typename T1, typename T2>
struct VecSum
{
    const T1& t1;
    const T2& t2;
    auto operator[](typename T2::size_type i) const
    {
        return t1[i] + t2[i];
    }
};

template<typename T1, typename T2>
struct VecDiff
{
    const T1& t1;
    const T2& t2;
    auto operator[](typename T2::size_type i) const
    {
        return t1[i] - t2[i];
    }
};

template<typename T1, typename T2>
auto operator+(const T1& t1, const T2& t2)
{
    return VecSum<T1, T2>{t1, t2};
}

template<typename T1, typename T2>
auto operator-(const T1& t1, const T2& t2)
{
    return VecDiff<T1, T2>{t1, t2};
}

int main()
{
    Vec<int> v1{1, 2, 3, 4, 5};
    Vec<int> v2{6, 7, 8, 9, 11};
    Vec<int> v3{3, 5, 2, 0, 17};

    Vec<int> v4 = v1+v2-v3;

    for (const auto& x: v4.data)
    {
        std::cout << x << ", ";
    }
    std::cout << std::endl;

    return 0;
}

The main advantage of this solution is that in the line Vec<int> v4 = v1+v2-v3; no additional temporaries of type Vec are created which increases performance.

I'd be grateful if someone could point potential drawbacks and possible further improvements of this code.