1

假设array是一个自定义类型,定义为本质上管理资源的类

class array {
public:
    size_t size;
    float *data;
};

为了使operator -to 执行元素级标量加法array并能够处理左右关联性array+floatfloat+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)确实解决了问题,但不是通用解决方案。所以问题是:

  1. 引擎盖下到底发生了什么,为什么根本不调用第二个重载?这与运算符优先级有关吗?
  2. 我的第二个问题是关于第二种情况,即2.0-(marray-5.0)在这里我们调用一次运算符 for thefloat+array和一次 for array+float。所以数组被遍历了两次。当存在多个相同运算符和/或多个运算符的倍数时,是否可以进行惰性评估以一次执行全局操作?

编辑: 是一个最小的工作示例。注意missing const在第二个重载中,我用另一个array operator -(const array& other)重载来消除歧义,用于两个数组的元素减法。我想这是第一个问题的原因。

4

1 回答 1

0

发生这种情况是因为您的“数组 - 浮点”运算符没有将数组作为 const 引用。结果,临时创建的2.0 - marray无法绑定到它。在链接到最小工作示例中,您使用2 - marray - 5,并且当编译器生成减去 5 的代码时,它将使用采用整数的构造函数构造一个新数组,然后在两个数组成员之间调用减法运算符。

将您的第二个减法运算符更改为array operator -(const array& lhs, float rhs).

于 2015-09-19T03:55:52.017 回答