2015-12-02 36 views
3

假设我想提供基于元素的算术运算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; 
} 
+0

要小心如果你提供元素明智的加法向量 - 确保'operator +'不会被误认为连接运算符... –

+0

还有[std :: valarray](http://en.cppreference。 com/w/cpp/numeric/valarray),但它不支持擦除,插入等。 – melak47

+0

@ melak47我知道'std :: valarray',但我实际上更喜欢'std :: vector' over'std: :valarray',请参阅[this](http://stackoverflow.com/questions/1602451)文章,例如。 – Marcel

回答

3

与相关的一切表现:资料的程序,看看会发生什么。

我的猜测是编译器不会完全优化代码 - 而且它可能永远不会有问题。要知道的唯一方法就是尝试一下。

+=的形式实现+的优点是已知这两个操作是等价的。这使得它不太可能发生错误。在放弃这个优势之前,你应该确保你的优化是必要的。由于很好的原因,C++的成语通常会成为习语。

1

你看过std::valarray吗?它已经提供了您需要的操作,您可能会从SIMD中受益。这可能是免费的性能++。