788 ______Часть II. Программирование на C++

Эта информация нужна вам по нескольким причинам. Одна из них — всегда полезно знать возможности компилятора. Еще более важная причина затрагивает отладочный процесс: вы должны понимать, что можно предпринять для трассировки и отладки.

Соответствие вызовов функций интерфейсам

Теперь нам известно, что для приведения кода в соответствие объявлением функции может понадобиться неявное одиночное преобразование. Помимо этого, .есть еще другие неявные, процессы, знакомство с которыми может быть очень полезным. C++ позволяет (и даже приветствует) перегрузку операций и функций. В главах 15 и 16 будут приведены примеры перегрузки, но сейчас нас больше интересует, как обнаруживать такие фрагменты в программах, нежели то, как их создавать.

Функции могут быть перегружены, исходя из типов своих аргументов. Если в программе имеет место наложение перегрузки функций на правило одного преобразования, то понять, какая же функция действительно вызывается, может оказаться нелегкой задачей. Попробуйте трассировать код программы в интегрированном отладчике (Integrated Debugger), но будьте готовы к тому, что результаты трассировки окажутся для вас неожиданными.

Когда аргументы относятся к родственным типам, например числовым, естественно заподозрить, что не обошлось без преобразования. Чтобы представить себе это, вообразите функцию, которая принимает double, а ей предлагается int — преобразование из int в double вполне осуществимо.

С другой стороны, если вы ясно видите функцию, в которой типы аргументов совершенно никак не связаны, то скорее всего имеет место перегрузка функции. При невозможности выполнения преобразования будет выдано сообщение об ошибке неопределенности. Если же не найдена соответствующая функция для перегрузки, то будет выдано сообщение об ошибке этого рода.

Еще более осложнить понимание происходящего может следующая, более тонкая ситуация. Допустим, вы видите код такого рода:

SomeType var;

cout « var;

Вы можете с уверенностью предположить одно из двух: где-то есть оператор-функция «, определенная для объектов типа SomeType, или же где-то есть операция преобразования. Оба предположения будут правдоподобны до тех пор, пока не будет напечатан адрес объекта. В главе 13 "Обзор потоков ввода-вывода" рассказывается о том, как оператор-функция « может быть перефужена для потокового вывода, а в главе 16 "Перегрузка операций" объясняется использование операций преобразования.

Ключевым моментом в поисках "эпицентра" является соответствие типов и обозначений. Если, например, вы нашли функцию operator«, принимаю-