Скажите, что я хочу предоставить элементарные арифметические операции operator+=
и operator+
для std::vector
для добавления элементов вектора по элементам. Часто я вижу operator+
реализуется в терминах operator+=
так:Арифметические операции над векторами
#include <algorithm>
#include <vector>
template<class Type>
std::vector<Type> & operator+=(std::vector<Type> &x, const std::vector<Type> &y) {
// Checks for equal size of x and y omitted here...
std::transform(std::begin(x), std::end(x), std::begin(y), std::begin(x), std::plus<Type>());
return x;
}
template<class Type>
std::vector<Type> operator+(std::vector<Type> x, const std::vector<Type> &y) {
// Checks for equal size of x and y omitted here...
return x += y;
}
int main() {
std::vector<double> v0{1.0, 2.0, 3.0};
auto v1 = v0;
auto v2 = v0;
v2 += v0; // yields [2, 4, 6]
auto v3 = v0 + v1; // yields [2, 4, 6]
return 0;
}
С точки зрения производительности, я думаю
template<class Type>
std::vector<Type> operator+(const std::vector<Type> &x, const std::vector<Type> &y) {
// Checks for equal size of x and y omitted here...
std::vector<Type> result;
result.reserve(x.size());
std::transform(std::begin(x), std::end(x), std::begin(y), std::back_inserter(result), std::plus<Type>());
return result;
}
является более эффективным, поскольку он позволяет избежать инициализации копию первого аргумента при вводе функция помещает результат непосредственно в неинициализированный блок памяти. Действительно ли стоит реализовать вторую версию или я могу предположить, что компилятор будет оптимизировать в любом случае? Кроме того, я считаю, что второй вариант менее общий, чем первый. Представьте себе, что-то вроде
#include <array>
#include <type_traits>
template<class Container, class Enable = void>
struct IsSequenceContainer: public std::false_type {
};
template<>
template<class Type, std::size_t size>
struct IsSequenceContainer<std::array<Type, size> >: public std::true_type {
};
template<>
template<class Type, class Allocator>
struct IsSequenceContainer<std::vector<Type, Allocator> >: public std::true_type {
};
// Use the following operations for std::array and std::vector
template<class Container>
typename std::enable_if<IsSequenceContainer<Container>::value, Container>::type operator+(Container x, const Container &y) {
return x += y;
}
Будьте осторожны, если вы обеспечиваете добавление элементов для векторов - убедитесь, что 'operator +' не ошибочно принимается за оператор конкатенации ... –
Существует также [std :: valarray] (http: //en.cppreference. com/w/cpp/numeric/valarray), но он не поддерживает стирание, вставку и т. д. – melak47
@ melak47 Мне известно о 'std :: valarray', но я бы предпочел' std :: vector' над 'std: : valarray', см. [this] (http://stackoverflow.com/questions/1602451) сообщение, например. – Marcel