测试两个valarray <double>相等的最佳方法?

时间:2015-06-29 21:22:53

标签: c++ valarray

我认为==的{​​{1}}的默认重载不太方便。默认情况下,valarray(对于两个valarrays x和y)返回x==y valarray<bool>true条目i。相反,我需要一个x[i]==y[i],它告诉我两个bool是否包含相同的元素。我知道我可以用一个循环来做这个,但每次都要做循环是不方便的。这里最好的解决方法是什么?有没有办法让我定义自己的valarray<double>重叠(以及==!=等等)?

4 个答案:

答案 0 :(得分:3)

“不太方便”?这种行为正是valarray的原因。

要覆盖它将完全弄巧成拙。

如果您不喜欢它,请改用vector

答案 1 :(得分:1)

请勿覆盖默认的operator==使用,例如:

bool isEqual( const std::valarray< bool >& aResult )
{
    bool equals = true;
    for ( auto item : aResult )
    {
        equals &= item;
    }
    return equals;
}

然后使用它:

std::valarray< int > x;
std::valarray< int > y;

bool equals = isEqual( x == y );

答案 2 :(得分:1)

我同意其他人不要覆盖==运算符。原因是那些运营商是使用valarray的主要原因。如果您不需要按元素操作,则不要使用valarray。你也可能需要操作员的原始版本,所以你为什么要把它扔掉?

我喜欢p.i.g的解决方案,但如果效率是一个主要问题,我会像这样修改它:

#include <iostream>
#include <valarray>

template <typename T>
bool isEqual( const std::valarray<T>& x,const std::valarray<T>& b) {
    using Iter = typename std::valarray<T>::const_iterator;
    using IterP = std::pair<Iter,Iter>;
    bool equals = true;

    for (IterP it(std::begin(x), std::begin(b));it.first != std::end(x);++it.first,++it.second) {
        equals &= ((*it.first) == (*it.second));
        if (!equals) break;
    }
    return equals;
}

并像这样使用

valarray<T> x,y;
bool b = isEqual(x,y);

如果不使用内置==,则不必比较valarray中的所有元素。

PS:

  

+只是一个例子。我也想要 - ,*等等。此外,我知道valarray有这些运算符的设计版本比一个天真的实现更有效(我认为他们使用代理类将中间结果存储在像x + y + z这样的表达式中,然后一起评估整个表达式)。我想利用这些。

实际上,那很有意思,我以前也不知道。结论应该是:不要覆盖那些操作符,否则你无法利用他们聪明的实现。

答案 3 :(得分:0)

如果您决定对商品“覆盖” std::valarray的{​​{1}}(而不是像user463035818's answer中那样编写命名函数),则可以编写一个自定义的“ adaptor”类:

operator==

如果您还希望能够将原始template<typename T> class CustomValArray : public std::valarray<T> { public: typedef std::valarray<T> base; // We need to re-implement any non-default constructors we want to use: CustomValArray(std::initializer_list<T> init) : base(init) {} }; /// Accumulation (single bool) comparison template<typename T> bool operator==(const CustomValArray<T> &lhs, const CustomValArray<T> &rhs) { return std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs)); } 用于operator==,则可以通过编写命名函数来实现:

std::valarray

注意:上面的代码段使用C ++ 14的自动返回类型推导。如果您使用的是C ++ 11,则应在声明程序的末尾添加类似/// Element-wise comparison template<typename T> auto elementWiseEqual(const CustomValArray<T> &lhs, const CustomValArray<T> &rhs) { // We delegate to operator==(const std::valarray<T> &, const std::valarray<T> &) typedef std::valarray<T> base; return dynamic_cast<const base &>(lhs) == dynamic_cast<const base &>(rhs); } 的内容。

Try it here.

如果您选择这样做,直接从-> decltype(std::valarray<T>() == std::valarray<T>())继承,请注意possible risks of inheriting from an STL class


或者,您可以使用具有std::valarray私有成员的包装器类,然后将要使用的任何成员函数手动委派给std::valarray<T>

相关问题