假设array
是一个自定义类型,定义为本质上管理资源的类
class array {
public:
size_t size;
float *data;
};
为了使operator -
to 执行元素级标量加法array
并能够处理左右关联性array+float
和float+array
,我们像这样重载它
array operator -(float lhs, const array& rhs)
{
array tmp(rhs.size);
for (size_t i=0;i<rhs.size;++i)
tmp.data[i] = lhs-rhs.data[i];
return tmp;
}
array operator -(array& lhs, float rhs)
{
array tmp(lhs.size);
for (size_t i=0;i<lhs.size;++i)
tmp.data[i] = lhs.data[i]-rhs;
return tmp;
}
假设我们也有一个initializer_list
构造函数,所以我们可以做
array marray = {1.0f,2.0f,3.0f,4.0f};
现在为
std::cout << marray-5.0 << "\n";
std::cout << 2.0-marray << "\n";
我们得到了想要的结果,但是这样做
std::cout << 2.0-marray-5.0 << "\n";
甚至不调用第二个重载marray-5.0
,并为输出数组的最后两个元素提供无意义的值,当然2.0-(marray-5.0)
确实解决了问题,但不是通用解决方案。所以问题是:
- 引擎盖下到底发生了什么,为什么根本不调用第二个重载?这与运算符优先级有关吗?
- 我的第二个问题是关于第二种情况,即
2.0-(marray-5.0)
在这里我们调用一次运算符 for thefloat+array
和一次 forarray+float
。所以数组被遍历了两次。当存在多个相同运算符和/或多个运算符的倍数时,是否可以进行惰性评估以一次执行全局操作?
编辑: 这是一个最小的工作示例。注意missing const
在第二个重载中,我用另一个array operator -(const array& other)
重载来消除歧义,用于两个数组的元素减法。我想这是第一个问题的原因。