std::vectorを拡張してみた(その後)

前回の「[std::vectorを拡張してみた](https://qiita.com/fred55/items/a0de8d7b2e9286f71923)」のその後です。
色々な指摘を受けて検討した結果、以下のようにしてみました。
エイリアスとグローバル関数を定義することで、`std::vector<double>`で四則演算や`mean,sd,norm`が計算できるようにしてみました。範囲for文が直観的だったので採用。

```c:my_vector.h
#include <vector>
#include <cmath>

using my_vector = std::vector<double>;

inline my_vector& operator+=(my_vector& lhs, const my_vector& rhs) {
    for (std::size_t i = 0; i < lhs.size(); i++)
        lhs[i] += rhs[i];
    return lhs;
}
inline my_vector& operator-=(my_vector& lhs, const my_vector& rhs) {
    for (std::size_t i = 0; i < lhs.size(); i++)
        lhs[i] -= rhs[i];
    return lhs;
}
inline my_vector& operator*=(my_vector& lhs, const my_vector& rhs) {
    for (std::size_t i = 0; i < lhs.size(); i++)
        lhs[i] *= rhs[i];
    return lhs;
}
inline my_vector& operator/=(my_vector& lhs, const my_vector& rhs) {
    for (std::size_t i = 0; i < lhs.size(); i++)
        lhs[i] /= rhs[i];
    return lhs;
}
inline my_vector& operator+=(my_vector& lhs, const double rhs) {
    for (auto& e : lhs) e += rhs;
    return lhs;
}
inline my_vector& operator-=(my_vector& lhs, const double rhs) {
    for (auto& e : lhs) e -= rhs;
    return lhs;
}
inline my_vector& operator*=(my_vector& lhs, const double rhs) {
    for (auto& e : lhs) e *= rhs;
    return lhs;
}
inline my_vector& operator/=(my_vector& lhs, const double rhs) {
    for (auto& e : lhs) e /= rhs;
    return lhs;
}

inline my_vector operator+(const my_vector& lhs, const my_vector& rhs) {
    return my_vector(lhs) += rhs;
}
inline my_vector operator-(const my_vector& lhs, const my_vector& rhs) {
    return my_vector(lhs) -= rhs;
}
inline my_vector operator*(const my_vector& lhs, const my_vector& rhs) {
    return my_vector(lhs) *= rhs;
}
inline my_vector operator/(const my_vector& lhs, const my_vector& rhs) {
    return my_vector(lhs) /= rhs;
}
inline my_vector operator+(const my_vector& lhs, const double rhs) {
    return my_vector(lhs) += rhs;
}
inline my_vector operator-(const my_vector& lhs, const double rhs) {
    return my_vector(lhs) -= rhs;
}
inline my_vector operator*(const my_vector& lhs, const double rhs) {
    return my_vector(lhs) *= rhs;
}
inline my_vector operator/(const my_vector& lhs, const double rhs) {
    return my_vector(lhs) /= rhs;
}

inline double mean(const my_vector& obj) {
    const std::size_t size = obj.size();
    if (size == 0) return 0;
    double t = 0;
    for (auto e : obj) t += e;
    return t / size;
}
inline double sd(const my_vector& obj) {
    const std::size_t size = obj.size();
    if (size < 2) return 0;
    double m = mean(obj);
    double t = 0;
    for (auto e : obj) t += (e - m) * (e - m);
    return std::sqrt(t / (size - 1));
}
inline double norm(const my_vector& obj) {
    double t = 0;
    for (auto e : obj) t += e * e;
    return std::sqrt(t);
}
```

追記

上記のヘッダーをgccでコンパイルすると以下のエラーが発生する。

```
error: invalid initialization of non-const reference of type 'my_vector& {aka std::vector<double>&}' 
from an rvalue of type 'my_vector {aka std::vector<double>}'
     return my_vector(lhs) += rhs;
            ^~~~~~~~~~~~~~
note:   initializing argument 1 of 'my_vector& operator+=(my_vector&, const my_vector&)'
 inline my_vector& operator+=(my_vector& lhs, const my_vector& rhs) {
```

一時的に生成される無名のオブジェクト(rvalue)を使用して、non-const referenceを初期化することはできないという意味らしい。以下のように修正すればコンパイルエラーは発生しない。

```cpp
// 変更前
inline my_vector operator+(const my_vector& lhs, const my_vector& rhs) {
    return my_vector(lhs) += rhs;
}

// 変更後
inline my_vector operator+(const my_vector& lhs, const my_vector& rhs) {
    my_vector t(lhs);
    return t += rhs;
}
```

生成したオブジェクトを変数に割り当てて、lvalueにしている。