我认为==
for的默认重载valarray
不是很方便。默认情况下x==y
(对于两个 valarrays x 和 y)返回 a valarray<bool>
,true
在i
第 th 条目上带有 if x[i]==y[i]
。相反,我需要一个bool
,它告诉我两者是否valarray<double>
包含相同的元素。我知道我可以用一个循环来做到这一点,但是每次都必须做这个循环并不方便。这里最好的解决方法是什么?有没有办法让我定义自己的重载==
(以及!=
,,<
等等)?
4 回答
“不太方便”?这种行为正是valarray
.
推翻它完全是弄巧成拙。
如果您不喜欢它,只需使用 avector
代替。
不要覆盖默认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 );
我同意其他人不超越==
运营商。原因是这些运算符是使用valarray
. 如果您不需要逐元素运算符,请不要使用valarray
. 此外,您可能在某些时候需要操作员的原始版本,那么您为什么要把它扔掉呢?
我喜欢 pig 的解决方案,但如果效率是一个主要问题,我会像这样修改它:
#include <utility>
#include <valarray>
template <typename T>
bool isEqual( const std::valarray<T>& x,const std::valarray<T>& b) {
bool equals = true;
for (auto it = std::make_pair(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);
通过不使用内置的,==
不必比较 valarrays 中的所有元素。
PS:
+
只是一个例子。我也想要-、*等。此外,我知道 valarray 有这些运算符的人为版本,它们比简单的实现更有效(我认为他们使用代理类将中间结果存储在 x + y + z 这样的表达式中,然后一起评估整个表达式)。我想利用这些。
实际上,这很有趣,我以前不知道。结论应该是:不要覆盖这些运算符,否则您将无法利用它们的巧妙实现。
如果您决定为商品“覆盖” std::valarray
(而不是像user463035818 的答案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==
for std::valarray
,您可以通过编写一个命名函数来实现:
/// 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);
}
注意:上面的代码片段使用了 C++14 的自动返回类型推导。如果您使用的是 C++11,则应该-> decltype(std::valarray<T>() == std::valarray<T>())
在声明符的末尾添加类似的内容。
如果您选择这样做,直接从 继承std::valarray
,请注意从 STL 类继承可能存在的风险。
作为替代方案,您可以拥有一个带有std::valarray<T>
私有成员的包装类,并手动将您想要使用的任何成员函数委托给std::valarray
.