我认为==
的{{1}}的默认重载不太方便。默认情况下,valarray
(对于两个valarrays x和y)返回x==y
valarray<bool>
,true
条目i
。相反,我需要一个x[i]==y[i]
,它告诉我两个bool
是否包含相同的元素。我知道我可以用一个循环来做这个,但每次都要做循环是不方便的。这里最好的解决方法是什么?有没有办法让我定义自己的valarray<double>
重叠(以及==
,!=
等等)?
答案 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);
}
的内容。
如果您选择这样做,直接从-> decltype(std::valarray<T>() == std::valarray<T>())
继承,请注意possible risks of inheriting from an STL class。
或者,您可以使用具有std::valarray
私有成员的包装器类,然后将要使用的任何成员函数手动委派给std::valarray<T>
。