Подтвердить что ты не робот

Почему объявление функции с аргументом const допускает вызов функции с аргументом non-const?

Обратите внимание на следующий код С++:

#include <iostream>
using std::cout;

int foo (const int);

int main ()
{
   cout << foo(3);
}

int foo (int a)
{
   a++;
   return a;
}

Обратите внимание, что прототип foo() принимает значение const int и что определение принимает int. Эта компиляция без ошибок...

Почему нет ошибок компиляции?

4b9b3361

Ответ 1

Поскольку для вызывающего объекта foo не имеет значения, изменяет ли foo свою копию переменной или нет.

В частности, в стандарте С++ 03 следующие два фрагмента объясняют, почему:

С++ 03 Раздел: 13.2-1

Две объявления функций с тем же именем относятся к одной и той же функции, если они находятся в одной области и имеют эквивалентные объявления параметров (13.1).

С++ 03 Раздел: 13.1-3

Объявления параметров, которые отличаются только наличием или отсутствием константы и/или летучих, эквивалентны. В этом случае игнорируются только константы-константы const и volatile на самом внешнем уровне спецификации типа параметра; const и volatile-спецификаторы, скрытые в спецификации типа параметра, являются значительными и могут использоваться для различения перегруженных деклараций функций.

Ответ 2

Верхний уровень const (т.е. применимый к переданному значению, а не к тому, на что он указывает или ссылается) влияет только на реализацию, а не на интерфейс, функции. Компилятор игнорирует его с точки зрения интерфейса (т.е. Вызывающей стороны) и применяет его только к реализации (т.е. Код в теле функции).

Ответ 3

Как объяснили другие, стандарт говорит, что это нормально, и что компилятор может позволить себе проявлять снисходительность к обеспечению этого, потому что он не влияет на вызывающего, но никто не ответил, почему компилятор должен быть мягким. Это не особенно мягко в целом, и программист, который просто смотрел на интерфейс, затем погружается в реализацию, может иметь это в глубине своего сознания, что параметр const, когда он нет, или наоборот - не очень хорошо.

Эта снисходительность позволяет изменять реализацию без изменения заголовков, которые с использованием традиционных инструментов делают триггеры перекомпиляции клиентского кода. Это может быть серьезной проблемой в развитии масштаба предприятия, где существенное изменение в заголовке низкого уровня (например, ведение журнала) может привести к перестройке практически всех объектов между ним и приложениями... тратить тысячи часов на процессорное время и задерживая всех и вся, ожидающих сборки.

Итак, это уродливо, но практическая уступка.

Я также ответил на другой аналогичный вопрос, который рассматривает, почему недогрузка f (const T) и f (T) не допускается - может представлять интерес для всех, кто это читает - Верхний уровень const не влияет на подпись функции

Ответ 4

int foo (const int a)
{
   a++;
   return a;
}

Это приведет к ошибке при компиляции.