Как предотвратить временное на левой стороне оператора присваивания - PullRequest
0 голосов
/ 10 апреля 2020

Если я определяю operator+ для типа, обычным образом

struct S {};

S operator+(S const &, S const &) { 
  return {}; 
}

пользователи S могут написать код, подобный

S s{};
s + s = S{}; // huh

Из того, что я могу сказать, operator+ возвращает временный объект типа S, который затем назначается. Затем объект умирает в конце оператора, потому что для него нет имени, и, таким образом, оператор фактически не используется.

Я не вижу никакого смысла в таком коде, поэтому я хотел бы хотел бы сделать это ошибка компиляции. Есть способ сделать это? Даже предупреждение было бы лучше, чем ничего.

Ответы [ 2 ]

0 голосов
/ 10 апреля 2020

Просто нашел то, что мне нужно здесь . Очевидно, я могу заставить оператор присваивания связываться только с lvalues.

struct S {
    S& operator=(S const&) & // only binds to lvalues
    { 
      return *this; 
    }
}; 

Теперь я получаю именно ту ошибку, которую хочу.

0 голосов
/ 10 апреля 2020

Один простой способ предотвратить это - вернуть константный объект:

const S operator+(S const &, S const &) { 
    return {}; 
}

В этом случае это приведет к ошибке компиляции, но

s= s + s;

все равно будет работать просто отлично.

Это, конечно, имеет несколько других последствий и может иметь или не иметь нежелательные побочные эффекты, которые могут создавать или не создавать проблему, но это будет новый вопрос здесь ...

...