Приоритет оператора для пользовательских типов и возможно ли иметь ленивую оценку, когда присутствуют кратные числа одного и того же оператора?

предполагать array это пользовательский тип, определенный как класс, который по существу управляет ресурсом

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

Чтобы сделать operator - выполнить поэлементное скалярное сложение 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) действительно решает проблему, но не является общим решением. Итак, вопрос:

  1. Что на самом деле происходит под капотом и почему вторая перегрузка вообще не вызывается? Связано ли это с приоритетом оператора?
  2. Мой второй вопрос касается второго случая, т.е. 2.0-(marray-5.0) здесь мы однажды позвоним оператору для float+array и один раз для array+float, Таким образом, массив пересекается дважды. Можно ли выполнять ленивую оценку для одновременного выполнения глобальной операции, когда присутствуют кратные числа одного и того же оператора и / или кратные числа нескольких операторов?

Редактировать: Вот это минимальный рабочий пример. Обратите внимание missing const во второй перегрузке, которую я использовал, чтобы устранить неоднозначность с другим array operator -(const array& other) перегрузка для поэлементного вычитания двух массивов. Я думаю, что это причина первой проблемы.

1

Решение

Это происходит потому, что ваш оператор «массив — число с плавающей точкой» не принимает массив в качестве константной ссылки. В результате временный созданный для 2.0 - marray не могу связать это В вашем связанном с минимальным рабочим примере вы используете 2 - marray - 5и когда компилятор генерирует код для вычитания 5, он создаст новый массив, используя конструктор, который принимает целое число, а затем вызовет оператор вычитания между двумя элементами массива.

Измените вашего второго оператора вычитания на array operator -(const array& lhs, float rhs),

0

Другие решения