C++: Tale of implicit conversion

C++: Tale of implicit conversion


Садитесь поудобнее, сегодня поучительная история о неявных преобразованиях в C++. 

Есть у структуры оператор равенства.

И даже работает он как ожидается:

Если потребуется проверить неравенство, можно использовать !(n1 == n2), а вот (n1 != n2) уже нельзя:

Определяем оператор неравенства, и снова всё работает:

Красота! А теперь то, за что мы любим C++ — подводные камни. Пример прямо из продуктового кода, баг на ровном месте. 

Есть другой коварный оператор — operator bool(). И он может сделать вызов (n1!=n2) валидным без всякого оператора неравенства. Только результат будет нехороший. 

Oops. Что произошло? Когда компилятор не нашел подходящего operator!=(), он неявно преобразовал операнды к bool, у которого есть стандартный operator!=(). 

Да и вообще никаких операторов сравнения не нужно, и так всё работает: 

*Ba-dum tsss* 

Чтобы избежать подобных казусов, C++ Core Guidelines (и мы) рекомендуют избегать неявных операторов преобразований, иными словами, помечать все пользовательские операторы конверсии ключевым словом explicit:

https://godbolt.org/z/f7d1azxb6 

...что запретит неявные преобразования к этому типу, и, например, в данном случае компилятор предупредит, если не хватает подходящего оператора сравнения. 

Report Page